SQL Oracle - 使用在第二个表

时间:2016-06-23 19:21:18

标签: sql oracle

表A

Store_Num   BKT1    BKT2    BKT3    BKT4    BKT5    BKT6    BKT7    BKT8    BKT9
111         1       2       1       0       3       2       4       2       5   

表B

Monthly_Bucket  Weekly_Buckets                                  
MBKT1           BKT3,BKT4,BKT5,BKT6                                 
MBKT2           BKT7,BKT8,BKT9,BKT10                                    

查询应该在表B.Monthly_Bucket列中查找Weekly_Buckets列中的相应值。然后将Weekly_Buckets列中的值作为列名称,以选择并汇总表A中的相应值 例如:在表B中,Monthly_Bucket让我们取值MBKT1,现在我们看到Weekly_Buckets列中MBKT1的对应值是BKT3,BKT4,BKT5,BKT6。
因此,我们将此值BKT3,BKT4,BKT5,BKT6分别作为列名处理每个值BKT3和BKT4以及BKT5和BKT6以选择数据并将这4列与表A中的一列相加。结果应如下所示< / p>

结果表

Store_Num   MBKT1                                   
111         6    (we got this by summing columns BKT3,BKT4,BKT5,BKT6)           

2 个答案:

答案 0 :(得分:0)

您的数据结构设计似乎需要规范化。

您可以尝试这样的查询,但效率可能非常低,您需要规范化数据以获得更好的结果:

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

答案 1 :(得分:0)

您可以使用like运算符,避免将weekly_buckets字符串拆分为组件,如下所示:

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;

结果:

 STORE_NUM MONTHLY_BUCKET MONTHLY_VALUE
---------- -------------- -------------
       111 MBKT1                      6
       111 MBKT2                     11

2 rows selected.

注意&#34;终止逗号&#34;在连接条件中(第二行到最后一行代码);没有那个丑陋的技巧,BKT1将匹配MBKT2聚合字符串中的BKT10,与您的要求相反。

修改

要获得按列排列的每月存储桶值,您可以使用pivot操作(假设您事先知道可能存储桶的名称),如下所示:

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      MBKT1      MBKT2
---------- ---------- ----------
       111          6         11