SQL - join,如果有多行,则根据列数据进行选择

时间:2013-05-23 09:16:24

标签: sql teradata

我正在根据名为acc_id

的列加入两个表(帐户,地址)

地址表有时会有多个地址与acc_id相关联,并且它们与类型列区分开来,标记地址是主地址还是辅地址。

我想加入acc_id上的两个表,地址表的列应该在结果中如下:

  • 如果没有地址,则为null
  • 如果存在1个地址,则该地址的列
  • 如果存在2个地址,则表示主要地址的列

如何在(Teradata-)SQL中执行此操作?

2 个答案:

答案 0 :(得分:2)

案例陈述可能适合您!

  • 在“地址”表格上进行两次左连接。
  • 其中一个连接条件应该是“主要”地址
  • 和另一个用于辅助地址。
  • 案例陈述首先检查主要地址
  • 如果一个不存在
  • 然后选择辅助地址。
  • 由于left outer join正在使用,如果两者都不存在,则该值将显示为NULL
      SELECT DISTINCT a.acc_id
           , CASE WHEN primary_add.acc_id IS NOT NULL 
                  THEN primary_add.address 
                  ELSE secondary_add.address
             END address
           , CASE WHEN primary_add.acc_id IS NOT NULL 
                  THEN primary_add.city
                  ELSE secondary_add.city
             END city 
           , CASE WHEN primary_add.acc_id IS NOT NULL 
                  THEN primary_add.state
                  ELSE secondary_add.state
             END state 
           , CASE WHEN primary_add.acc_id IS NOT NULL 
                  THEN primary_add.zip
                  ELSE secondary_add.zip
             END zip 
           , CASE WHEN primary_add.acc_id IS NOT NULL 
                  THEN primary_add.address_type
                  ELSE secondary_add.address_type
             END address_type
          ------------------------------------------------
         FROM account AS a
          ------------------------------------------------
         LEFT OUTER JOIN address AS primary_add 
           ON     a.acc_id = primary_add.acc_id 
              AND address_type = 'primary'
          ------------------------------------------------
         LEFT OUTER JOIN address AS secondary_add 
           ON     a.acc_id = secondary_add.acc_id 
              AND address_type = 'secondary'

答案 1 :(得分:2)

这是一个更简单的Teradata解决方案:

SELECT   a.acc_id
       , b.*
FROM     account a
LEFT JOIN address b
ON      b.acc_id=a.acc_id
QUALIFY ROW_NUMBER() OVER (PARTITION BY a.acc_id
                           ORDER BY     b.address_type) = 1

QUALIFY是Teradata扩展程序,非常方便。使用PARTITION BY子句构建分区,并按ORDER BY子句排序。然后QUALIFY将使用ROW_NUMBER函数保留每个分区中的第一行。

当然,我假设您的 address_type 列具有您想要的排序值。如果值实际上是“主要”和“次要”,则按所示的升序排序应该有效(当两个值都存在时选择“主要”)。如果需要,您还可以在CASE子句中使用ORDER BY表达式。

我还强烈建议明确命名地址表所需的列。您对没有地址需要“空值”的评论意味着您需要LEFT JOIN