【问题标题】:Choosing Single Row from multiple rows - Teradata从多行中选择单行 - Teradata
【发布时间】:2016-08-24 05:23:12
【问题描述】:

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

表 1:

表2:

预期结果:

下面是我们需要的逻辑。

    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 放在上述案例陈述中,我得到的是 Hub3 而不是 Hub2。

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

如果您需要任何进一步的信息,请告诉我。

【问题讨论】:

  • 您的 Teradata 版本是什么?
  • 版本为 14.10.07.05

标签: teradata


【解决方案1】:

我认为你最好的选择是两次加入表 2。第一次,就像你在这里做的一样,但在idhub 上都使用LEFT OUTER JOIN。然后第二次在 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 值来使用相关子查询。

【讨论】:

  • 谢谢,但我无法访问左外连接内的 t1.hub。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多