SQL Oracle—使用作为值(行)存储在第二个表中的列名对第一个表中的列中的值求和

SQL 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

表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)           
表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)。