Teradata SQL:最大(最大)、第二大和第三大列名

Teradata SQL: Max (greatest), 2nd and 3rd greatest column names

我在 Teradata 中有一个包含 6 列的 table,如下所示:

ID   Feature1   Feature2   Feature3  Feature4  Feature5
1     12          15          1         22       350
2     121         0.9         999      756       879
...

我需要获取每行最大、第二大和第三大值的列名,因此,我需要如下所示的输出:

ID   Greatest    2nd_Greatest   3rd_Greatest
1    Feature5     Feature4         Feature2
2    Feature3     Feature5         Feature4

有人可以帮忙吗

谢谢!

您可以使用大量 case 语句来执行此操作,如果任何值是 NULL,这将变得更加复杂。不过,那将是最快的方法。

最简单的方法可能是取消数据透视并重新汇总数据:

select id,
       max(case when seqnum = 1 then feature end) as greatest_feature,
       max(case when seqnum = 2 then feature end) as greatest_feature2,
       max(case when seqnum = 3 then feature end) as greatest_feature3,
       max(case when seqnum = 1 then which end) as which_1,
       max(case when seqnum = 2 then which end) as which_2,
       max(case when seqnum = 3 then which end) as which_3
from (select id, feature, row_number() over (partition by id order by feature desc) as serqnum
      from ((select id, feature1 as feature, 'feature1' as which from table) union all
            (select id, feature2 as feature, 'feature2' as which from table) union all
            (select id, feature3 as feature, 'feature3' as which from table) union all
            (select id, feature4 as feature, 'feature4' as which from table) union all
            (select id, feature5 as feature, 'feature5' as which from table) union all
            (select id, feature6 as feature, 'feature6' as which from table)
           ) t
      ) t
group by id;

优化 Gordon 的查询:

您可以为这些 UNION 创建一个特征列表,然后交叉连接它,而不是多次遍历源 table:

SELECT t.id, f.feature, 
   CASE f.feature
      WHEN 'feature1' THEN t.feature1
      WHEN 'feature2' THEN t.feature2    
      WHEN 'feature3' THEN t.feature3
      WHEN 'feature4' THEN t.feature4
      WHEN 'feature5' THEN t.feature5
   END AS val
FROM tab AS t CROSS JOIN 
 (
   SELECT * FROM (SELECT 'feature1' AS feature) AS dt 
   UNION ALL
   SELECT * FROM (SELECT 'feature2' AS feature) AS dt 
   UNION ALL
   SELECT * FROM (SELECT 'feature3' AS feature) AS dt 
   UNION ALL
   SELECT * FROM (SELECT 'feature4' AS feature) AS dt 
   UNION ALL
   SELECT * FROM (SELECT 'feature5' AS feature) AS dt 
  ) AS f

您可以像上面那样使用 UNION 或作为真正的 table.

即时创建列表

从 TD14.10 开始还有一个 TD_UNPIVOT table 运算符(但仍然没有 PIVOT):

SELECT *
FROM TD_UNPIVOT
 (
   ON (SELECT id, feature1, feature2, feature3, feature4, feature5 FROM tab)
   USING
      VALUE_COLUMNS('val')
      UNPIVOT_COLUMN('feature')
      COLUMN_LIST('feature1', 'feature2', 'feature3', 'feature4', 'feature5')
 ) AS dt

同样从 TD14.10 开始,还有 LAST_VALUE 可用于与 ROW_NUMBER 一起查找第 n 个最大值,从而避免最终聚合:

SELECT id, 
   feature AS "Greatest",
   LAST_VALUE(feature)
   OVER (PARTITION BY id ORDER BY val DESC
         ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS "2nd_Greatest",
   LAST_VALUE(feature)
   OVER (PARTITION BY id ORDER BY val DESC
         ROWS BETWEEN 2 FOLLOWING AND 2 FOLLOWING) AS "3rd_Greatest"
FROM TD_UNPIVOT
 (
   ON (SELECT id, feature1, feature2, feature3, feature4, feature5 FROM tab)
   USING
      VALUE_COLUMNS('val')
      UNPIVOT_COLUMN('feature')
      COLUMN_LIST('feature1', 'feature2', 'feature3', 'feature4', 'feature5')
 ) AS dt
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY val DESC) = 1;