【问题标题】:At-least-one-in-group-like SQL queries至少一个组中的 SQL 查询
【发布时间】:2018-09-17 07:37:12
【问题描述】:

客户信息

zipcode|id|familyid|lastname|firstname|head
00001|0001|0001|NAME1|PAUL|1
00001|0002|0001|NAME1|JOHANNA|0
00002|0003|0001|NAME1|FRANCIS|0
...
00003|0004|0004|NAME2|PATRICE|1
00003|0005|0004|NAME2|PAULA|0
00003|0006|0004|NAME2|BART|0
...
00004|0007|0007|NAME3|PAT|1
00004|0008|0007|NAME3|JANE|0
00003|0009|0007|NAME3|BURT|0
...

假设有一个名为 CLIENTINFO 的表,其中包含 以下列:邮政编码、客户端 ID、 familyid、lastname、firstname 和 head(无论是 客户是否是他/她的一家之主)。家庭 id对应户主的id。

首先,您如何将以下查询转换为 SQL 95+:

显示至少有一个成员有邮政编码的家庭 与其他成员不同

例如,FRANCIS NAME1 的邮政编码与 PAUL 的不同 和弗朗西斯的。

二、你如何将下面的语句翻译成SQL:

显示至少有一个成员的邮政编码不同的家庭 来自一家之主。

例如,BURT NAME3 的邮政编码与 PAT NAME3 的邮政编码不同。

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。
  • 到目前为止你的尝试是什么?
  • 您想获取所有家庭成员还是只获取家庭 ID?顺便说一句,Q2 完全包含在 Q1 中:-)
  • @dnoeth,只有当有一家之主时:-)
  • @DavidFaber: 嗯,family id对应着family head的id,没有head就没有family :-)

标签: sql group-by teradata


【解决方案1】:

两个问题完全相同,当规则#1为真时,规则#2也为真,反之亦然。

要仅获取家庭 id,您可以使用简单的聚合:

select familyid
from CLIENTINFO 
group by familyid
having -- at least two different zipcodes
   min(zipcode) <> max(zipcode)

要获取所有家庭成员,您可以使用 Windowed Aggregates

select *
from CLIENTINFO 
qualify -- at least two different zipcodes 
   min(zipcode) over (partition by familyid)
<> max(zipcode) over (partition by familyid)

【讨论】:

  • 不一样的,如果head 和member 是不同的,这意味着家主不算是一个成员。 (但这听起来很奇怪)。
  • 这个解决方案认为邮政编码是数字是理所当然的。如果其中一个邮政编码包含字母,例如“000A1”)怎么办?
  • 它也可以。 &lt;&gt; 只是一个 not equal,也适用于字符。顺便提一句。 != 在 Teradata 中不起作用,它必须是 &lt;&gt;not =
【解决方案2】:

要获取邮政编码与户主不同的家庭,您可以执行以下操作:

SELECT * FROM clientinfo c1
 WHERE c1.head = 1
   AND EXISTS ( SELECT 1 FROM clientinfo c2
                 WHERE c2.familyid = c1.familyid
                   AND c2.id != c1.id
                   AND c2.zipcode != c1.zipcode );

如果所有家庭都有“头”,那么这也足以回答第一个问题;如果不是,则省略head 上的过滤器:

SELECT * FROM clientinfo c1
 WHERE EXISTS ( SELECT 1 FROM clientinfo c2
                 WHERE c2.familyid = c1.familyid
                   AND c2.id != c1.id
                   AND c2.zipcode != c1.zipcode );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2014-04-17
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多