如何选择不在另一个表中的记录?

时间:2015-09-01 19:30:05

标签: mysql sql select

我需要比较两个表并获取未完成或不存在的pn。 我似乎无法在任何地方在线找到答案,正是我需要的。以下是我需要的表格和示例输出。非常感谢谁能帮助我。

表1:

+------------+----------+------------+----+---------------------+
| cert       | job      | pcmk       | pn | stat                |
+------------+----------+------------+----+---------------------+
| MF21600001 | 6216     | A148       | 1  | 2015-08-14 13:20:29 |
| MF21600001 | 6216     | A148       | 2  |                     |
+------------+----------+------------+----+---------------------+

表2:

+-----------+----------+----+
| job       | pcmk     | pn |
+-----------+----------+----+
| 6216      | A148     | 1  |
| 6216      | A148     | 2  |
| 6216      | A148     | 3  |
+-----------+----------+----+

Table2中不在Table1或status = blank / NULL:

中的行的示例输出
+------------+------+------+----+
| cert       | job  | pcmk | pn |
+------------+------+------+----+
| MF21600001 | 6216 | A148 | 2  |
| MF21600001 | 6216 | A148 | 3  |
+------------+------+------+----+

好的,我接受了第一个想法并且玩了一下。

SELECT Table1.cert, pninput.job, pninput.pcmk, pninput.pn, pn.stat
FROM   Table1, Table2
WHERE  NOT EXISTS (SELECT *
                   FROM   Table1
                   WHERE  Table1.pcmk = Table2.pcmk AND Table1.job = Table2.job AND Table1.stat = '')

然而,现在每个证书都与每个pcmk和作业配对,即使每个证书只能有1个作业和1个pcmk,并且还需要35秒以上才能运行

3 个答案:

答案 0 :(得分:1)

如果我改写您的情况,您希望来自table2的行不会在table中具有非null状态的相应行。这听起来像exists条件:

SELECT *
FROM   table2
WHERE  NOT EXISTS (SELECT *
                   FROM   table1
                   WHERE  table1.pn = table2.pn AND stat IS NOT NULL)

答案 1 :(得分:0)

您可以采用的一种方法是从t1获取非pn值列表:

SELECT pn
FROM table1
WHERE stat IS NOT NULL;

然后,您可以从table2中提取不在该组中的所有值。这将考虑table1中根本不在的所有pn值,以及table1中具有null状态的值:

SELECT *
FROM table2
WHERE pn NOT IN(
  SELECT pn
  FROM table1
  WHERE stat IS NOT NULL);

以下是SQL Fiddle示例。

答案 2 :(得分:0)

Clarification: One job can have multiple pcmk and comparision should be done for each pcmk

SELECT t1.cert,t2.job,t2.pcmk,t2.pn
FROM table1 t1
join table2 t2 on (t1.pcmk=t2.pcmk)
WHERE (t1.pn=t2.pn and (t1.stat="" or t1.stat is null)) 
or t2.pn NOT IN(
  SELECT pn
  FROM table1
  WHERE table1.pcmk=t2.pcmk)
  group by t2.pcmk,t2.pn;

Assumption: Query is for single job. For multiple job, add job check in where-clause,on-clause' andgroup by` as well.