所以这里基本上就是这个问题(我将这变成一个更普遍的问题,以防人们将来需要这样的东西)。
我有一张桌子(" People")基本上是这个
╔══════════╦═══════╗
║ PersonID ║ Letter║
╠══════════╬═══════╣
║ 1 ║ A ║
║ 1 ║ B ║
║ 1 ║ C ║
║ 1 ║ D ║
║ 2 ║ A ║
║ 2 ║ B ║
║ 2 ║ C ║
║ 3 ║ B ║
║ 3 ║ C ║
║ 4 ║ A ║
║ 4 ║ C ║
║ 4 ║ D ║
║ 5 ║ E ║
╚══════════╩═══════╝
让我说我有另一张桌子(" Letters"),它可以列出所有可能的"字母"一个人可以拥有。
╔══════════╦══════╗
║ LetterID ║ Text ║
╠══════════╬══════╣
║ 1 ║ A ║
║ 2 ║ B ║
║ 3 ║ C ║
║ 4 ║ D ║
║ 5 ║ E ║
╚══════════╩══════╝
我需要制作一张新表,列出所有人员和他们不具备的信件。所以对于这个例子,结果将是这个
╔══════════╦══════════════╗
║ PersonID ║ LetterNotHad ║
╠══════════╬══════════════╣
║ 1 ║ E ║
║ 2 ║ D ║
║ 2 ║ E ║
║ 3 ║ A ║
║ 3 ║ D ║
║ 3 ║ E ║
║ 4 ║ B ║
║ 4 ║ E ║
║ 5 ║ A ║
║ 5 ║ B ║
║ 5 ║ C ║
║ 5 ║ D ║
╚══════════╩══════════════╝
非常感谢任何和所有帮助或指导。
编辑:这基本上就是我在尝试的东西,像这样
select p.PersonId, l.value
from letters l
left join people p
on l.Text = p.Letter
where p.personid is null
答案 0 :(得分:0)
这是一个想法
WITH cte
AS (SELECT *
FROM (SELECT DISTINCT personid
FROM people) B
CROSS JOIN (SELECT DISTINCT Text as letter
FROM letters) A)
SELECT *
FROM cte c
WHERE NOT EXISTS (SELECT 1
FROM first_table f
WHERE c.personid = f.personid
AND c.letter = f.letter)
注意:您需要在letterid
表格中使用People
而不是Letter
,并定义foreign key
,以使表格保持一致
答案 1 :(得分:0)
因此,要查找缺失值,您要执行的操作是生成表示所有可能值的集合。这是两组(人和字母)之间的笛卡尔积,在SQL中,您使用cross join
运算符(或非限定联接)来执行此操作。
从这个集合中你想要删除你已经拥有的组合,其余的将是遗漏的组合。
有很多方法可以做到这一点;使用左连接它可能看起来像这样:
select sub.*
from (
select distinct personid, text
from people
cross join letters
) sub
left join people p on p.letter = sub.text and p.personid = sub.personid
where p.personid is null
或使用except
集合运算符(对于MSSQL(Oracle中的minus
) - MySQL没有这个):
select personid, text from people cross join letters
except
select personid, letter from people