SQL Oracle—使用作为值(行)存储在第二个表中的列名对第一个表中的列中的值求和
表ASQL Oracle—使用作为值(行)存储在第二个表中的列名对第一个表中的列中的值求和,sql,oracle,Sql,Oracle,表A Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9 111 1 2 1 0 3 2 4 2 5 Monthly_Bucket Weekly_Buckets MBKT1 BKT
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
表B
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
查询应在表B中查找。每月_Bucket列中的相应值在每周_Bucket列中。然后将“每周”列中的值作为列名,选择表A中相应的值并求和例如:在表B中,让我们取值MBKT1,现在我们看到周桶列中MBKT1的对应值为BKT3、BKT4、BKT5、BKT6。
因此,我们取这个值BKT3、BKT4、BKT5、BKT6,并将每个值BKT3和BKT4以及BKT5和BKT6分别作为列名,以选择数据并将这4列相加为表A中的一列。结果如下所示
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
结果表
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
数据结构的设计似乎需要规范化。
您可以尝试这样的查询,但可能效率很低,您需要规范化数据以获得更好的结果:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
SELECT store_num, monthly_bucket, sum( some_value )
FROM (
SELECT *
from TABLEA
UNPIVOT (
some_value FOR col_name IN ( BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9 )
)
) a
JOIN (
select monthly_bucket, trim(column_value) Weekly_Buckets
from tableb, xmltable(('"' || replace(Weekly_Buckets, ',', '","') || '"'))
) b
ON b.Weekly_Buckets = a.col_name
GROUP BY store_num, monthly_bucket
STORE_NUM MONTH SUM(SOME_VALUE)
---------- ----- ---------------------------------------
111 MBKT1 6
111 MBKT2 11
您可以使用
like
操作符,避免将每周\u bucket
字符串拆分为组件,如下所示:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
with table_a (store_num, BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9) as (
select 111, 1, 2, 1, 0, 3, 2, 4, 2, 5 from dual
),
table_b (monthly_bucket, weekly_buckets) as (
select 'MBKT1', 'BKT3,BKT4,BKT5,BKT6' from dual union all
select 'MBKT2', 'BKT7,BKT8,BKT9,BKT10' from dual
),
table_a_unpivot (store_num, weekly_bucket, weekly_value) as (
select * from table_a
unpivot (
weekly_value for
weekly_bucket in (BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9)
)
)
select a.store_num, monthly_bucket, sum(weekly_value) as monthly_value
from table_a_unpivot a
join table_b b
on b.weekly_buckets || ',' like '%' || a.weekly_bucket || ',%'
group by store_num, monthly_bucket;
with table_a (store_num, BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9) as (
select 111, 1, 2, 1, 0, 3, 2, 4, 2, 5 from dual
),
table_b (monthly_bucket, weekly_buckets) as (
select 'MBKT1', 'BKT3,BKT4,BKT5,BKT6' from dual union all
select 'MBKT2', 'BKT7,BKT8,BKT9,BKT10' from dual
),
table_a_unpivot (store_num, weekly_bucket, weekly_value) as (
select * from table_a
unpivot (
weekly_value for
weekly_bucket in (BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9)
)
),
m (store_num, monthly_bucket, weekly_value) as (
select a.store_num, b.monthly_bucket, a.weekly_value
from table_a_unpivot a
join table_b b
on b.weekly_buckets || ',' like '%' || a.weekly_bucket || ',%'
)
select * from m
pivot (sum(weekly_value) for monthly_bucket in ('MBKT1' as MBKT1, 'MBKT2' as MBKT2));
结果:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
STORE_NUM MONTHLY_BUCKET MONTHLY_VALUE
---------- -------------- -------------
111 MBKT1 6
111 MBKT2 11
2 rows selected.
STORE_NUM MBKT1 MBKT2
---------- ---------- ----------
111 6 11
注意连接条件中的“终止逗号”(代码的倒数第二行);如果没有这种难看的技巧,BKT1将匹配MBKT2聚合字符串中的BKT10,这与您的要求相反
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
编辑:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
要获得列中排列的每月桶值,可以使用pivot
操作(假设您事先知道可能桶的名称),如下所示:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
with table_a (store_num, BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9) as (
select 111, 1, 2, 1, 0, 3, 2, 4, 2, 5 from dual
),
table_b (monthly_bucket, weekly_buckets) as (
select 'MBKT1', 'BKT3,BKT4,BKT5,BKT6' from dual union all
select 'MBKT2', 'BKT7,BKT8,BKT9,BKT10' from dual
),
table_a_unpivot (store_num, weekly_bucket, weekly_value) as (
select * from table_a
unpivot (
weekly_value for
weekly_bucket in (BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9)
)
)
select a.store_num, monthly_bucket, sum(weekly_value) as monthly_value
from table_a_unpivot a
join table_b b
on b.weekly_buckets || ',' like '%' || a.weekly_bucket || ',%'
group by store_num, monthly_bucket;
with table_a (store_num, BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9) as (
select 111, 1, 2, 1, 0, 3, 2, 4, 2, 5 from dual
),
table_b (monthly_bucket, weekly_buckets) as (
select 'MBKT1', 'BKT3,BKT4,BKT5,BKT6' from dual union all
select 'MBKT2', 'BKT7,BKT8,BKT9,BKT10' from dual
),
table_a_unpivot (store_num, weekly_bucket, weekly_value) as (
select * from table_a
unpivot (
weekly_value for
weekly_bucket in (BKT1, BKT2, BKT3, BKT4, BKT5, BKT6, BKT7, BKT8, BKT9)
)
),
m (store_num, monthly_bucket, weekly_value) as (
select a.store_num, b.monthly_bucket, a.weekly_value
from table_a_unpivot a
join table_b b
on b.weekly_buckets || ',' like '%' || a.weekly_bucket || ',%'
)
select * from m
pivot (sum(weekly_value) for monthly_bucket in ('MBKT1' as MBKT1, 'MBKT2' as MBKT2));
结果:
Store_Num BKT1 BKT2 BKT3 BKT4 BKT5 BKT6 BKT7 BKT8 BKT9
111 1 2 1 0 3 2 4 2 5
Monthly_Bucket Weekly_Buckets
MBKT1 BKT3,BKT4,BKT5,BKT6
MBKT2 BKT7,BKT8,BKT9,BKT10
Store_Num MBKT1
111 6 (we got this by summing columns BKT3,BKT4,BKT5,BKT6)
STORE_NUM MONTHLY_BUCKET MONTHLY_VALUE
---------- -------------- -------------
111 MBKT1 6
111 MBKT2 11
2 rows selected.
STORE_NUM MBKT1 MBKT2
---------- ---------- ----------
111 6 11
我正试图从上面的解决方案中运行一个select查询,但出现错误:ORA-02000:缺少列关键字::从tableb中选择每月_bucket,修剪(列_值)每周_bucket,xmltable(“'”| |替换(每周_bucket),“,”,“)| |'”)非常感谢。谢谢你的帮助!嘿这很好,但我需要的最后一件事是以下格式的数据:STORE_NUM MBKT1 MBKT2 111 6 11最初问问题时没有这样说的任何特殊原因?抱歉最初可能是我的问题引起的误解。但我想我在“结果表”下的问题中提到了我正在寻找的格式。实际上我收回了它,你是对的-你显然希望MBKT1作为列标题,而不是表中的值。您可以透视结果(稍后我将演示如何),但您需要知道哪些MBKTx值将预先存在(否则您需要动态SQL)。