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

时间:2016-07-02 07:18:45

标签: mysql sql

我想创建一份报告。

我有两张桌子:

  1. student_list
  2. transaction_list
  3. 这是表格中包含的行

    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
    

    现在我想从transaction_list中存在的student_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 | -        | -
    

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

4 个答案:

答案 0 :(得分:2)

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添加的列上)并将该行保留在结果集中。

答案 1 :(得分:2)

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

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

您可以执行以下操作:

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子句中完成此操作。

答案 2 :(得分:0)

试试这个;)

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

答案 3 :(得分:0)

感谢@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月"对于" March",它的效果和我想要的一样。