【问题标题】:Teradata sql Analytics - derived a new column for partitioned clauseTeradata sql Analytics - 为分区子句派生新列
【发布时间】:2020-06-05 08:06:49
【问题描述】:

我有一个 Book 表,我想派生一个新列 word1,如下所示:

书:

+-------+------+------+------+ |姓名 |页 |线 |词 | +-------+------+------+------+ |书1 | 1 | 1 |该| +-------+------+------+------+ |书1 | 1 | 2 |一个 | +-------+------+------+------+ |书1 | 1 | 3 |时间 | +-------+------+------+------+ |书1 | 1 | 4 |一个 | +-------+------+------+------+ |书1 | 2 | 1 |安| +-------+------+------+------+ |书1 | 2 | 2 |汤姆 | +-------+------+------+------+ |书1 | 2 | 3 |一个 | +-------+------+------+------+ |书1 | 3 | 1 |一个 | +-------+------+------+------+ |书1 | 3 | 2 |杰克 | +-------+------+------+------+ |书1 | 3 | 3 |一个 | +-------+------+------+------+ |书1 | 4 | 1 |自从 | +-------+------+------+------+ |书1 | 4 | 2 |他们| +-------+------+------+------+ |书1 | 4 | 3 |山姆 | +-------+------+------+------+

派生Word1为
案例
如果同一页面的任何一行有“The”,那么“The”
如果同一页面的任何一行有“An”,则为“An”
如果同一页面的任何一行具有“A”,则为“A”
其他
第 1 行的单词

+-------+------+------+--------+-------+ |姓名 |页 |线 |词 |单词1 | +-------+------+------+--------+-------+ |书1 | 1 | 1 |该|该| +-------+------+------+--------+-------+ |书1 | 1 | 2 |一个 |该| +-------+------+------+--------+-------+ |书1 | 1 | 3 |时间 |该| +-------+------+------+--------+-------+ |书1 | 1 | 4 |一个 |该| +-------+------+------+--------+-------+ |书1 | 2 | 1 |安|安| +-------+------+------+--------+-------+ |书1 | 2 | 2 |汤姆 |安| +-------+------+------+--------+-------+ |书1 | 2 | 3 |一个 |安| +-------+------+------+--------+-------+ |书1 | 3 | 1 |一个 |一个 | +-------+------+------+--------+-------+ |书1 | 3 | 2 |杰克 |一个 | +-------+------+------+--------+-------+ |书1 | 3 | 3 |一个 |一个 | +-------+------+------+--------+-------+ |书1 | 4 | 1 |自从 |自从 | +-------+------+------+--------+-------+ |书1 | 4 | 2 |他们|自从 | +-------+------+------+--------+-------+ |书1 | 4 | 3 |山姆 |自从 | +-------+------+------+--------+-------+

【问题讨论】:

    标签: sql teradata window-functions


    【解决方案1】:

    这只是一个窗口函数和case:

    select t.*,
           (case when sum(case when word = 'The' then 1 else 0 end) over (partition by page) > 0
                 then 'The'
                 when sum(case when word = 'An' then 1 else 0 end) over (partition by book, page) > 0
                 then 'An'
                 when sum(case when word = 'A' then 1 else 0 end) over (partition by book, page) > 0
                 then 'A'
                 else max(case when line = 1 then word end) over (partition by book, page)
            end) as derived_word            
    from t;
    

    【讨论】:

    • 而不是 line=1,如果 min(line) then word,我该如何更改它。
    • @D.Aquar 。 . .你会使用first_value()
    【解决方案2】:

    您可以使用窗口函数。 colaesce() 可以方便地简化这里的逻辑:

    select 
        b.*,
        coalesce(
            max(case when word = 'The' then word end) over(partition by name, page),
            max(case when word = 'An'  then word end) over(partition by name, page),
            max(case when word = 'A'   then word end) over(partition by name, page),
            max(case when line = 1     then word end) over(partition by name, page)
        ) word1
    from book b
    

    【讨论】:

    • 这实际上并没有产生正确的输出,它将第一个匹配的 'The','An','A' 分配给每一行。我想让同一分区窗口的所有行(记录)都具有 'The' 或 'An' 或 'A' 。
    • @D.Aquar:窗口定义中有错字(book 而不是page) - 已修复。
    【解决方案3】:

    如果您希望在没有 window functions 的情况下执行此操作

    select a.*, b.word1
    from cte a
    left join (select name, page ,coalesce(max(case word when 'the' then word end) 
                                          ,max(case word when'an' then word  end) 
                                          ,max(case word when 'a' then word end)
                                          ,max(case line when 1 then word end)) as word1
               from cte
               group by name, page) b on a.name=b.name and a.page=b.page;
    

    DEMO

    【讨论】:

      【解决方案4】:

      应用 FIRST_VALUE 并按优先级排序:

      SELECT ...
         First_Value(word) 
         Over (PARTITION BY NAME, page
               ORDER BY 
                  CASE word 
                    WHEN 'The' THEN 1
                    WHEN 'An'  THEN 2
                    WHEN 'A'   THEN 3
                    ELSE 99
                  END, line)
      FROM tab
      

      【讨论】:

      • 这是实现结果的好方法。谢谢。
      猜你喜欢
      • 2016-01-18
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 2019-04-14
      • 2016-02-27
      • 2014-07-01
      • 2016-09-25
      • 2021-07-02
      相关资源
      最近更新 更多