SQL 连接:输入、输出、摇动一切

发布于 2024-09-30 22:56:28 字数 644 浏览 11 评论 0原文

我正在执行以下 sql 以返回数据,其中 table1 和 table1 中的 dob 和地址都匹配。 2.

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate
group by table1.dob, table1.address
order by table1.dob, table1.address

但是,当表2中没有匹配项且只有该数据时,我现在想从表1返回数据,我认为简单地将内连接更改为左外连接就可以执行我所要求的操作,但事实并非如此。

谢谢!

I am performing the follwing sql to return a data where there is a match of both dob and address in tables1 & 2.

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate
group by table1.dob, table1.address
order by table1.dob, table1.address

However I now want to return the data from table1 when there is no match in table2 and only that data, I thought simply changing inner join to left outer would perform what I required, it does not.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忘你却要生生世世 2024-10-07 22:56:28

如果连接中没有匹配项,则第二个表中的字段为 NULL,因此您必须检查 table2 中是否有 NULL 值。假设 table2 中的 dob 不为 NULL,这应该可以解决您的问题:

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
left outer join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate and table2.dob is null
group by table1.dob, table1.address
order by table1.dob, table1.address

If there is no match in the join, the field from the second table are NULL, so you have to check for a NULL value in table2. Assuming dob is NOT NULL in table2, this should solve your problem:

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
left outer join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate and table2.dob is null
group by table1.dob, table1.address
order by table1.dob, table1.address
嘴硬脾气大 2024-10-07 22:56:28

在这种情况下,没有连接,您应该使用

In this case thre's not a join, you should use NOT EXISTS function.

新雨望断虹 2024-10-07 22:56:28

在我看来,LEFT JOIN 更干净,如果 LEFT JOIN 和 NOT EXISTS 的性能没有太大差异,您应该使用它。 @JNK 说“EXISTS 和 NOT EXISTS 通常比连接或其他运算符(如 IN)更快,因为它们短路 - 当它们第一次命中时,它们会转到下一个条目”,但我的理解是 NOT EXISTS 和 NOT IN 是通常很昂贵,因为 sql server 必须遍历查找表中的所有记录以确保该条目实际上不存在,所以我不知道短路是如何工作的

In my opinion LEFT JOIN is much more cleaner and you should go with that if there is no big difference between the performance of LEFT JOIN and NOT EXISTS. @JNK said "EXISTS and NOT EXISTS are ordinarily faster than joins or other operators like IN because they short circuit - the first time they get a hit they move on to the next entry", but my understanding is that NOT EXISTS and NOT IN are usually expensive as sql server has to go through all the records in the lookup table to make sure that the entry in fact does NOT EXIST, so i dont know how the short circuit would work

帅的被狗咬 2024-10-07 22:56:28

您还可以在此处使用 EXCEPT 关键字。

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
where table1.dob > @myDate
EXCEPT
select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate

这将获得第一个查询中第二个查询中没有的所有记录。

You could also use the EXCEPT keyword here.

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
where table1.dob > @myDate
EXCEPT
select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate

That would get you all of the records in the first query that are not in the second query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文