如何找到另一个表中找不到的行?

时间:2012-12-30 17:02:20

标签: mysql sql database

我在两个表itemlog

之间有一个1-1列关系

对于每个项目,都有一个日志,用于存储项目是否已被处理。这由log.itemId标识为item.idlog.status告诉处理是否正在进行,或已完成(-1正在等待,1正在完成)。

在处理开始之前,log表中没有item表中相应项目的行。

我正在尝试从项目中获取行,其中日志中没有相应的行(意味着处理尚未开始)或者状态不是1(意味着其待定)。

我疯狂地想弄明白,这是我的疑问:

SELECT 
    item.id
FROM item, log
WHERE log.itemId != item.id
OR (log.itemId = item.id AND log.status !='1')
ORDER BY item.id ASC LIMIT 1

然而,这会返回一个空结果。

我做错了什么?

4 个答案:

答案 0 :(得分:4)

试试这个:

SELECT 
  item.id
FROM
  item left join log on (log.itemId = item.id)
WHERE
  log.itemId is null
  OR log.status !='1'
ORDER BY item.id LIMIT 1

答案 1 :(得分:2)

虽然提供的其他答案很有用并且很常见(外部联接和外部表上的NULL检查),但SQL中还有另一种更直接适用的方法:

SELECT
item.id
FROM item
WHERE
not exists
    (SELECT itemID from log where log.itemID = item.id and log.status = '1')

我建议尝试两者并确定哪个操作更快 - 外部联接检查NULL与“不存在”语法。大多数数据库不会优化两个查询相同(即使结果相同),因此一个可能会胜过另一个,尽管并不总是明显哪个更好。

请注意,我在最后一行更改了!= =,但我认为这是正确的,尽管我可能误解了逻辑。

答案 2 :(得分:1)

其中一个决定是使用EXISTS(http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html),你在下面找到的例子或者你可以使用LEFT JOIN。

SELECT *
FROM item AS i
WHERE NOT EXISTS(
    SELECT *
    FROM log AS l
    WHERE l.itemId = i.id
        AND l.status != 1
)
LIMIT 0, 1;

答案 3 :(得分:0)

这是另一种方法:

SELECT item.id FROM item WHERE item.id NOT IN (SELECT itemid FROM log where log.status != '1')