SQL:选择在另一个表

时间:2016-01-31 02:22:59

标签: mysql sql sql-server database sql-server-2008

所以这里基本上就是这个问题(我将这变成一个更普遍的问题,以防人们将来需要这样的东西)。

我有一张桌子(" 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

2 个答案:

答案 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