繁体   English   中英

如何选择另一个表中不存在的行

[英]How do I select rows which do not exists in another table

我想创建一份报告。

我有2张桌子:

  1. student_list
  2. transaction_list

这是这些表中包含的行

student_list

Stud_ID | Name
1       | Cat
2       | Dog
3       | Rabbit

transaction_list

Trans_ID | Stud_ID | Payment_Month
1        | 1       | January
2        | 1       | February

现在我想从student_list中选择存在于transaction_list中的数据,并将其与student_list中的数据相结合,这些数据在transaction_list中不存在,其中Payment_Month =“January”

我试过这个查询

SELECT Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
  ON t.Stud_ID = s.Stud_ID
WHERE Payment_Month = "January"
UNION
SELECT Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
  ON t.Stud_ID = s.Stud_ID
WHERE t.Stud_ID IS NULL

而我得到了这个

Name   | Trans_ID | Payment_Month
Cat    | 1        | January
Dog    | -        | -
Rabbit | -        | -

但是,当我将查询中的Payment_Month值更改为“March”时,我得到了这个

Name   | Trans_ID | Payment_Month
Dog    | -        | -
Rabbit | -        | -

不是我想要的,因为我喜欢这个

Name   | Trans_ID | Payment_Month
Cat    | -        | -
Dog    | -        | -
Rabbit | -        | -

无论如何我能得到那个吗?

SELECT Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
  ON (t.Stud_ID = s.Stud_ID AND Payment_Month = "January")
UNION
SELECT Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
  ON t.Stud_ID = s.Stud_ID
WHERE t.Stud_ID IS NULL

试试吧。 通过使用WHERE您可以根据查询提供的实际结果进行过滤,因此,如果您的LEFT JOIN传递null但是您要对该列进行过滤,则会从结果集中删除该行。

通过将月份置于JOIN条件中,它将在此列上返回null(在JOIN添加的列上)并将行保留在结果集中。

您正在使用OUTER JOIN,因此请充分利用它。

  • 无论是否匹配, Outer joins返回Outer joins一侧的所有行。
  • 因此,当您在( 外部QUERY上运行PREDICATE时,您将消除将返回您仍希望看到的值的行。

您可以执行以下操作:

SELECT Name, B.Trans_ID, Stud_ID B.Payment_Month
FROM student_list A
LEFT OUTER JOIN (SELECT TRANS_ID, PAYMENT_MONTH, Stud_ID
                 FROM   transaction_list
                 WHERE  PAYMENT_MONTH = "January") B
ON A.Stud_ID = B.Stud_ID

它将返回1月份transaction_list所在的ID以及student_list未匹配的所有匹配项。 公平地说,您可能希望消除查询中的重复项,因此您可以在GROUP BY子句中完成此操作。

试试这个;)

SELECT Name, COALESCE(Trans_ID, '-') AS Trans_ID, COALESCE(Payment_Month, '-') AS Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
ON t.Stud_ID = s.Stud_ID
AND NOT EXISTS (
    SELECT 1 FROM transaction_list tl WHERE tl.Stud_ID = t.Stud_ID AND tl.Payment_Month = 'January'
)

SQLFiddle DEMO HERE

感谢@Philipp

这是适合我的代码:

SELECT Stud_Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
ON (t.Stud_ID = s.Stud_ID AND Payment_Month= "January")
UNION
SELECT Stud_Name, Trans_ID, Payment_Month
FROM student_list s
LEFT JOIN transaction_list t
ON t.Stud_ID = s.Stud_ID
WHERE t.Stud_ID IS NULL

即使我将“1月”改为“3月”,它也能像我想要的那样奏效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM