MySQL必须匹配2个表中的两列...否则返回空结果?

时间:2014-06-16 14:44:55

标签: php mysql database join

我有一个像这样的SQL查询:

SELECT t1.key, t1.value
FROM table1 AS t1, table2 AS t2
WHERE t1.pID IN (45, 67, 88, 32) AND t2.id = t1.id;

这似乎返回t1.pId IN (45, 67, 88, 32)的所有行,但它不应该因为t2.id应该进一步减少行结果,但似乎不是这样做。

我需要减少通过t2.id返回的行,但是如果在对t1.pId values数组进行排序后找不到t2.id,则应返回空结果。

EDITED 表,尝试选择t1列,而不是t2,抱歉。但只有满足两个条件,并且仅在第二个条件为真后才返回结果行。此外,现在修复表格,使其正确。

2 个答案:

答案 0 :(得分:1)

您的查询返回符合指定条件的每一行。也就是说,它仅检查单个行是否满足谓词,并返回所执行的行,而不管任何不行的行。

如果我理解你要问的是什么(而且我并不完全确定我这么做),你说你想要回复一个空集"当某些行满足t1.id上的谓词时,但t1中至少有一行在t2中没有匹配的行。

检查是否有任何行没有"匹配"在t2中,我们可以使用反连接模式(还有其他方法......

SELECT SUM(1) AS t1_rows_not_matched
  FROM table1 t1
  LEFT
  JOIN table2 t2
    ON t2.id = t1.id
 WHERE t1.pID IN (45, 67, 88, 32)
   AND t2.id IS NULL

将其合并到您的查询中,您可以将其用作内联视图,并包含一个谓词来检查不匹配的行数,例如:

SELECT d.key
     , d.value
  FROM ( SELECT SUM(1) AS cnt_rows_not_matched
           FROM table1 t1
           LEFT
           JOIN table2 t2
             ON t2.id = t1.id
          WHERE t1.pID IN (45, 67, 88, 32)
            AND t2.id IS NULL
       ) c
 CROSS
  JOIN table1 d
 WHERE d.pID IN (45, 67, 88, 32)
   AND c.cnt_rows_not_matched = 0

这可能无法解答您提出的问题,但目前尚不清楚您的要求。


单独检查每一行。如果a满足谓词,则返回。只有在没有匹配的行时,您发布的查询才会返回空集。

您可能希望检查至少有一行与列表中包含的每个pID值相匹配。也就是说,例如,如果没有pID值为32的行,那么您希望查询返回一个空集,而不是符合条件的行集。

SELECT d.key
     , d.value
  FROM ( SELECT SUM(1) AS cnt_rows_not_matched
           FROM table1 t1
           LEFT
           JOIN table2 t2
             ON t2.id = t1.id
          WHERE t1.pID IN (45, 67, 88, 32)
            AND t2.id IS NULL
       ) c
 CROSS
  JOIN ( SELECT COUNT(DISTINCT f.pID) AS cnt_pid
           FROM table1 f
          WHERE f.pID IN (45, 67, 88, 32)
       ) p
 CROSS
  JOIN table1 d
 WHERE d.pID IN (45, 67, 88, 32)
   AND c.cnt_rows_not_matched = 0
   AND p.cnt_pid = 4

答案 1 :(得分:0)

我不确定加入表的逗号语法是否会导致MySQL做一些你不期望的事情,但是如果你重写它以使用一个明确的JOIN,那么我认为你会发现它更清楚你的地方条件是和JOIN如何发生。这是一个建议:

SELECT t2.key, t2.value
FROM table1 AS t1
LEFT OUTER JOIN table2 AS t2 ON t1.id = t2.id
WHERE t1.id IN (45, 67, 88, 32)
      AND t2.id IS NOT NULL

这里的想法是你明确加入表t2,并声明它应该如何加入。

然后,通过在t2.id中删除所有带有NULL的行,将行减少到仅成功连接的行。如果在t2.id

上加入时没有匹配的t2行,则t1.id = t2.id将为null