【问题标题】:(probably) very simple SQL query needed(可能)需要非常简单的 SQL 查询
【发布时间】:2018-04-23 17:44:45
【问题描述】:

度过了缓慢的一天....可以使用一些帮助来编写一个简单的 ANSI SQL 查询。

我有一个家庭中的个人列表(名字和姓氏),还有一个列出这些个人子集的第二个表格。如果第二个表中未列出任何个人,我想创建第三个表来标记家庭中的每个人。目标本质上是标记“不完整”的家庭。

下面是两个输入表的示例,以及所需的第三个表。

正如我所说...非常简单...度过了缓慢的一天。谢谢!

【问题讨论】:

  • 共享表结构、样本数据和异常输出。另外,标记您正在使用的 RDBMS。
  • 你好拉胡尔。我添加了一张显示问题的图片。我正在使用 SAS,它利用 ANSI SQL。
  • 为什么 Diane Thomsom 会不完整?
  • @GordonLinoff 我猜,因为她的家人 - Barb 和 Jack 不在第二张桌子上
  • 图片数据是一个真正的编码问题。

标签: sql ansi-sql


【解决方案1】:

我想你想要一个 left joincase 表达式:

select t1.*,
       (case when t2.first_name is null then 'INCOMPLETE' else 'OK' end) as flag
from table1 t1 left join
     table2 t2
     on t1.first_name = t2.first_name and t1.last_name = t2.last_name;

当然,这将“Diane Thomson”标记为“OK”,但我认为这是问题中的错误。

编辑:

哦,我明白了。姓氏定义了家庭(这似乎是一个很大的假设)。但是您可以使用窗口函数来做到这一点:

select t1.*,
       (case when count(t2.first_name) over (partition by t1.last_name) =
                  count(*) over (partition by t1.last_name)
             then 'OK'
             else 'INCOMPLETE'
        end) as flag
from table1 t1 left join
     table2 t2
     on t1.first_name = t2.first_name and t1.last_name = t2.last_name;

【讨论】:

  • 感谢 Gordon - 这非常有效(但在 SAS 中不行)!
【解决方案2】:

这并不简单,至少在 SAS 中不是这样 :-)

标准 SQL,当支持 Windowed Aggregates 时:

select ft.*,
  -- counts differ when st.first_name is null due to the outer join
  case when count(*) over (partition by ft.last_name)
          = count(st.first_name) over (partition by ft.last_name)
       then 'OK'
       else 'INCOMPLETE'
  end
from first_table as ft
left join second_table as st
  on ft.first_name = st.first_name
 and ft.last_name = ft.last_name

否则你需要一个标准的聚合并加入:

select ft.*, st.flag
from first_table as ft
join 
 (
    select ft.last_name,
      case when count(*) 
              = count(st.first_name)
           then 'OK'
           else 'INCOMPLETE'
      end as flag
    from first_table as ft
    left join second_table as st
      on ft.first_name = st.first_name
     and ft.last_name = st.last_name
    group by ft.last_name
 ) as st
on ft.last_name = st.last_name

【讨论】:

  • @Keith:对于 SAS,我更喜欢 Tom 的解决方案,它应该更有效,它是 *Windowed Aggregate 的专有版本 :-)
【解决方案3】:

如果您想利用 SAS 的非 ANSI SQL 功能,即自动将聚合函数结果重新合并回详细记录,那么在 SAS 中很容易做到。

select
   a.first
 , a.last
 , case when 1=max(missing(b.last)) then 'INCOMPLETE' 
        else 'OK' 
   end as flag 
 from table1 a left join table2 b
   on a.last=b.last and a.first=b.first 
 group by 2
 order by 2,1
;

【讨论】:

  • 感谢您的回复。我已经使用了其他海报的解决方案,但我会将您的解决方案归入“必知”类别!
猜你喜欢
  • 2021-07-09
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多