复杂 - 返回数据库中找不到的信息

时间:2011-02-24 17:20:53

标签: mysql

我有一个奇怪的查询要从网站执行。我有一组数组包含许多表中的相关ID - 每个数组1个表。例如(数组名称是表的名称):

Array Set 1:
array "q": 1,2,3
array "u": 1,5
array "k": 7

Array Set 2:
array "t":   2,12
array "o":  8, 25

Array Set 3 (not really a set):
array "e": 5

我有另一个表Alignment,它没有数组表示。它执行一对多关系,允许来自表q,u和k(数组1,并在表中记录为relType / relID)的记录链接到来自t和o的记录(数组2,记录为keyType) / keyID)和e(数组3,记录为keyType / keyID)。示例如下:

Table: Alignment
 id   keyType  keyID   relType  relID 
 1       e       5        q       1
 2       o       8        q       1
 3       o       8        u       1
 4       t       2        q       2
 5       t       2        k       7
 6       t      12        q       1

因此,在记录6中,表t中id为12的记录被链接到表q中id为1的记录。

我必须找到缺失的链接。 理想状态是数组1中的每个id在对齐表中都有一条记录,将它们与数组2 中的至少1条记录相关联。在示例中,对齐记录1不计入此目标,因为它将set 1 id与set 3 id(而不是set 2)对齐。

扫描表格,您可以快速看到阵列集1中缺少一些ID:“q”-3和“u”-5。

我一直用脚本来做这个,循环遍历每个set 1数组并查找相应的记录,这会生成一大堆sql调用并真正杀死任何调用此函数的页面。

有没有办法在单个sql语句中完成此操作?

我希望结果如何(理想情况下):

记录集(神奇地包含表中不存在的数据):

relType   |    relID
    q            3
    u            5

但是,即使是数据库中的二进制类型答案,我也会感到高兴 - 找到了所有正确的ID:true或false? (虽然缺少记录数组是其他函数所必需的,但至少我可以在快速和慢速选项之间进行选择。)

哦,MySQL 5.1。

用户Damp使用临时表,连接和IS NULL语句给了我很好的答案。但是在我加入皱纹之前,有一个第三个数组必须从结果中排除,这也破坏了IS NULL部分。我编辑了他的sql语句,如下所示:

SELECT *
FROM k2
LEFT JOIN alignment
USING ( relType, relID )
HAVING alignment.keyType IS NULL
OR alignment.keyType = "e"

我也尝试过使用Group By relID(我一直认为这是HAVING子句的要求)。问题是我的结果集包含“q”-1,它链接到所有三种类型的记录(“o”,“t”和“e”)。我需要排除这个结果,但我不确定如何。


这是我最终的SQL:

SELECT *
FROM k2
LEFT JOIN (

    SELECT *
    FROM alignment
    WHERE keyType != 'e' and 
    ( 
    (relType = 'q' AND relID IN ( 1, 2, 3 ))
    OR 
    (relType = 'u' AND relID IN ( 1, 5 ))
    OR 
    (relType = 'k' AND relID IN ( 7 ))
    )

    )A
    USING ( relType, relID )
    HAVING keyType Is Null

我必须使用脚本转储IN限定符的值。关键是不要直接加入对齐表。

1 个答案:

答案 0 :(得分:0)

你可以尝试走这条路:

DROP TABLE IF EXISTS k2;
CREATE TEMPORARY TABLE k2 (relType varchar(10),relId int);
INSERT INTO k2 VALUES 
  ('q',1),
  ('q',2),
  ('q',3),
  ('u',1),
  ('u',5),
  ('k',7);
SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
HAVING Alignment.keyType IS NULL 

这适用于小型表格。虽然不确定非常大......

修改

如果要添加WHERE语句,查询将如下所示

SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
WHERE Alignment.keyType != 'e'
HAVING Alignment.keyType IS NULL