从一个表中获取Col值,其中cols表示为不同表中的行值

时间:2018-04-08 16:45:10

标签: sql oracle

我的数据库中有以下表格:

表T1:

Item | Week

101  | Week1

101  | Week2

102  | Week1

102  | Week3

表2:

Item | Week1 | Week2 | Week3

101  | 10    |10     | 20

102  | 20    | 20    | 30 

我希望输出为:

Item | Total_Value

101  | 20

102  | 50

以下是要求:

  • 从Table1中选择Row值,并从另一个表中获取和聚合所选行值的列值(Table1的行值= Table2的Col名称)。

  • 需要一个效率更高的解决方案,因为周数可以从1 ... 104开始。

  • 要在Oracle 11g中执行的编码;最好是可以在较低版本中使用的解决方案。但性能优先考虑:)

  • 伪代码会有很大的帮助。

提前致谢。

3 个答案:

答案 0 :(得分:0)

unpivot table2,例如:

SELECT *
FROM   table2
UNPIVOT (item FOR week IN (week1 AS 'Week1', week2 as 'Week2', .....));

你可以用传统方式加入table1和table2。

答案 1 :(得分:0)

正如评论中已经说过的,更好的方法是改变表格设计。你说,

  

表2实际上有104周列

那么,那些列确实是Week1,week2,week3 ...week104吗?

对于您显示的3列,UNPIVOT的查询将是这样的。

SELECT Item
    ,SUM(val) as Total_Value
FROM (
    SELECT *
    FROM T2
    UNPIVOT(val FOR Week IN (
                 Week1 as 'Week1'
                ,Week2 as 'Week2'
                ,Week3 as 'Week3'
                ))
    ) t
WHERE EXISTS (
        SELECT 1
        FROM t1
        WHERE t1.Item = t.Item
             AND t1.Week = t.week
        )
GROUP BY Item
Order By Item;

Demo

请注意,我们必须为每个可用列编写Week? as 'Week?',这本身当然有点繁琐,导致不必要的长查询。所以,如果你真的想要它,或者想出一个替代设计,请仔细考虑并实施它。

答案 2 :(得分:0)

联盟全部也可能有用

select t2.Item, sum(t2.value) Total_value from (
    select item, week1 as value, 'Week1' weeks from t2 union all
    select item, week2 as value, 'Week2' weeks from t2 union all
    select item, week3 as value, 'Week3' weeks from t2 ) t2
where exists (
    select 1 from t1 
    where item = t2.item and Week = t2.weeks)
group by t2.Item