Select 数据在其他 table 中没有键

Select Data not have a key in other table

我有两个table 1- 日期 Table

------------
|    Date   |
------------
| 1/11/2020 |
-----------
| 2/11/2020 |
------------

2- 收入

    ------------------------------------
    |  revDate  |  Name     |  Revenue  |
    ------------------------------------
    | 1/11/2020 |  Joe      |   500 $   |
    ------------------------------------
    | 2/11/2020 |   Dani    |   400 $   |
    ------------------------------------
    | 4/11/2020 |   Sami    |   300 $   |
    ------------------------------------

我需要查询 return 用户名未在日期 table 提交收入 查询应该 return :

    ------------------------------------
    |  Date     |  UserNotSubmit        |
    ------------------------------------
    | 1/11/2020 |  Dani                 |
    ------------------------------------
    | 1/11/2020 |  Sami                 |
    ------------------------------------
    | 2/11/2020 |  Joe                  |
    ------------------------------------
    | 2/11/2020 |  Sami                 |
    ------------------------------------

您可以按如下方式使用反加入:

SELECT D.DATE, R.NAME FROM DATES D
JOIN REVENUE R ON D.DATE <> R.REVDATE

您可以使用 cross join 生成日期和姓名的所有组合,然后过滤掉存在的组合:

select d.date, n.name
from dates
cross join (select distinct name from revenues) n
where not exists (select 1 from revenues r where r.revdate = d.date and r.name = n.name)

您可以递归应用 CROSS JOIN 然后 LEFT JOIN 例如

SELECT rr.revDate AS Date, rr.Name AS UserNotSubmit
  FROM
  ( SELECT r1.revDate, r2.Name, r1.Name AS Name2
      FROM Revenues r1
     CROSS JOIN Revenues r2) rr
  LEFT JOIN Revenues r3
         ON r3.revDate != rr.revDate
        AND r3.Name = rr.Name 
 WHERE r3.revDate IS NOT NULL
 ORDER BY rr.revDate

更新: 事实上,上面的查询带来了所有不匹配的记录,而不需要 Date table,但是如果你想过滤掉由于 DateDate table 的匹配值,然后应用一个简单的 (INNER) JOIN 例如

WITH Rev AS
(
SELECT rr.revDate AS Date, rr.Name AS UserNotSubmit
  FROM
  ( SELECT r1.revDate, r2.Name, r1.Name AS Name2
      FROM Revenues r1
     CROSS JOIN Revenues r2) rr
  LEFT JOIN Revenues r3
         ON r3.revDate != rr.revDate
        AND r3.Name = rr.Name 
  WHERE r3.revDate IS NOT NULL
)
SELECT r.*
  FROM Rev r
  JOIN Date d
    ON d.Date = r.Date
  ORDER BY r.Date

Demo