从多行中选择单行 - Teradata

时间:2016-08-23 18:57:20

标签: teradata

我有以下要求选择最新状态。

表1:

enter image description here

表2:

enter image description here

预期结果:

enter image description here

以下是我们需要的逻辑。

    SELECT
        Table1.ID,
       ,CASE WHEN (Table1.hub=Table2.hub) THEN Table2.Status ELSE NULL END AS Original_Status
       ,CASE WHEN (Table1.hub<>Table2.hub AND Table2.Status like 'Found%' ) THEN Table2.hub ELSE NULL END AS Derived_Hub
       ,CASE WHEN (Table1.hub<>Table2.hub AND Table2.Status like 'Found%' ) THEN Table2.Status ELSE NULL END AS Derived_Status
from
    Table1 
Join Table2
    ON (Table1.ID=Table2.ID)

使用此代码,我得到3行。如果我将max放在上面的case语句中,我将获得Hub3而不是Hub2。

您能否告诉我如何将所有内容合并为一行。请注意,我想显示表2中最新发现的状态,即使有2个已找到状态的集线器。

如果您需要任何进一步的信息,请与我们联系。

2 个答案:

答案 0 :(得分:0)

我认为你最好的选择是两次加入表2。第一次,就像你在这里一样,但在LEFT OUTER JOINid使用hub。然后第二次在table2的派生版本上,你只按时间戳按降序排序时选择前1条记录:

SELECT
    t1.id,
    t1.hub as "Original Hub"
    t2.status as "Original Hub Status",
    t3.hub as "Found Hub",
    t3.status as "Found Hub Status"
FROM
    Table1 t1
    LEFT OUTER JOIN Table2 t2 ON
        t1.id = t2.id AND 
        t1.hub = t2.hub
    LEFT OUTER JOIN 
        (
            --Select a hub with the same id, that doesn't share the same hub number
            --Only choose the top record when sorted by timestamp in descending order           
            SELECT TOP 1 id, hub, status
            FROM table2
            WHERE t1.hub <> table2.hub
            ORDER BY TimeStamp Desc
        ) t3 ON
        t1.id = t3.id

具有别名t3的子查询通过引用其WHERE语句中的t1.hub值来使用相关子查询。

答案 1 :(得分:0)

在TD14.10中,您可以使用LAST_VALUE来访问“最后”行的数据。 CASE基于您的查询:

SELECT
   t2.ID, 
   CASE WHEN t1.Hub = t2.Hub THEN t2.Hub END AS Original_Hub, 
   CASE WHEN t1.Hub = t2.Hub THEN t2.Status END AS Original_Status, 
   -- get the last Hub
   LAST_VALUE(CASE WHEN t1.Hub <> t2.Hub AND Table2.Status like 'Found%'
                   THEN t2.Hub
              END)
   OVER (PARTITION BY t1.ID
         ORDER BY CASE WHEN t1.Hub = t2.Hub THEN 0 ELSE 1 END, t2.TS 
         ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Derived_Hub,
   -- get the last Status
   LAST_VALUE(CASE WHEN t1.Hub <> t2.Hub AND Table2.Status like 'Found%'
                   THEN t2.Status
              END)
   OVER (PARTITION BY t1.ID
         ORDER BY CASE WHEN t1.Hub = t2.Hub THEN 0 ELSE 1 END, t2.TS
         ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Derived_Status
FROM
    Table1 AS t1
JOIN Table2 AS t2
    ON (t1.ID=t2.ID)  
QUALIFY
   ROW_NUMBER () -- return the 1st row only
   OVER (PARTITION BY t1.ID
         ORDER BY CASE WHEN t1.Hub = t2.Hub THEN 0 ELSE 1 END, t2.TS) = 1

EXPLAIN应将所有OVER合并为一个STATS步骤,因为它们使用相同的PARTITION BYORDER BY