2012-12-30 30 views
2

我有两个表,itemlog如何查找在其他表中找不到的行?

对于每个项目之间的1-1列关系,还有存储项目是否已经被处理或不日志。这由log.itemId等于item.id确定。 log.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 

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

我在做什么错?

+0

如果你想要所有的行,为什么要有'limit 1'? –

回答

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

一个决定是使用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; 
+0

在子查询中使用'l.itemId'和'limit 1'子句的索引,这应该是最有效的解决方案。 –

0

这里是另一种方式来做到这一点:

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

这不值得赞赏,因为它没有正确回答问题。 –

+0

您错过了状态逻辑,答案是错误的。 – sorencito

2

而对方的回答提供的作品,是很常见的(外连接和外部表NULL检查),另外还有一个在SQL方法更直接适用:

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

我会建议您尝试两种,并确定其运行速度更快 - 外连接检查空主场迎战“不存在”语法。大多数数据库不会优化两个相同的查询(即使结果相同),所以其中一个可能会优于另一个,尽管并不总是明显哪个更好。

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