[英]Getting count of rows from one table where at least one related item from another table matches criteria
[英]Getting rows from one table that do not have related rows in other tables meeting specific criteria without subquery
這是SQL提琴 。
我有一張帶有名稱列表的表。 我想獲取所有在相關表中沒有具有特定狀態('S')或在第3個表中的字段(與第二個表相關)中滿足某個狀態('A'的字段)的名稱的列表')。
我已經能夠使用SQL小提琴及其下面顯示的子查詢來完成此操作,但是如果可能的話,我希望在沒有子查詢的情況下執行此操作。
SELECT * FROM name_table LEFT JOIN
(SELECT b.name_id FROM b LEFT JOIN c ON (b.c_id = c.id) WHERE (c.c_status = 'A') OR (b.b_status='S'))
results ON (name_table.id=results.name_id)
WHERE results.name_id IS NULL;
在我的示例中,我想要“ Ted Andrews”和“ Jack Johnson”行
不包含“ John Doe”,因為表C具有狀態為“ A”的行。不包含“ Bill Smith”,因為表B具有狀態為“ S”。不包含“ Jim Scott”,因為表C具有狀態為“ A”的行'(即使表C中還有另一行的狀態為“ A”)
SELECT * FROM name_table
LEFT JOIN b ON (name_table.id = b.name_id)
LEFT JOIN c ON (b.c_id = c.id) AND (c_status = 'A');
WHERE (b.b_status IS NULL) OR ((b.b_status <> 'S') AND (c.id IS NULL));
嘗試錯誤地包含“ Jim Scott”
我會這樣做( sqlfiddle ):
SELECT nt.first, nt.last
FROM name_table nt
LEFT JOIN b ON nt.id = b.name_id
LEFT JOIN c ON nt.id = c.a_id
GROUP BY first, last
HAVING SUM(IF(b.b_status = 'S',1,0)) = 0
AND SUM(IF(c.c_status = 'A',1,0)) = 0;
擁有位僅用於計數狀態符號實例,這些實例將人員排除在所需結果集中,並且不需要任何實例。
SELECT name_table.id, min(first) as first, min(last) as last
FROM name_table
LEFT JOIN b ON name_table.id = b.name_id
LEFT JOIN c ON b.c_id = c.id
GROUP BY name_table.id
HAVING
count(case when b.b_status = 'S' then 1 end) = 0
and count(case when c.c_status = 'A' then 1 end) = 0;
由於您必須查看c
中的多行以確定是否有匹配項,因此您會發現自己使用某種聚合。 我個人認為查詢不是那么可怕。
即使您說不應該將Jim Scott包括在內,但在我看來,他的b_status都不是“ S”,c_status也不是“ A”。 這是您要找的東西嗎?
select * from name_table
join b on name_table.id = b.name_id and b.b_status <> 'S'
join c on b.c_id = c.id and c.c_status <> 'A';
這是一種不使用子查詢的方法,盡管我想針對大型數據集檢查其性能:
SELECT a.*
FROM name_table AS a
LEFT JOIN b ON a.id = b.name_id
LEFT JOIN c ON b.c_id = c.id
GROUP BY a.id
HAVING MIN((b.b_status IS NULL OR b.b_status <> 'S') AND (c.c_status IS NULL OR c.c_status <> 'A'));
HAVING
子句的每一行求值為0或1,以表明它是否符合您的條件,然后在所有名稱中取最小值,以確保排除Jim Jim Scott-僅包括所有聯接行與您的條件匹配的名稱。
在這種情況下not exists
會有所幫助
select
*
from name_table t
where not exists (select null from B
where t.id = b.name_id and b.b_status = 'S')
and not exists (select null from C
where t.id = c.a_id and c.c_status = 'A')
演示結果 :
| id | first | last |
|----|-------|----------|
| 3 | Ted | Anderson |
| 5 | Jack | Johnson |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.