SQL简化了一个except查询

时间:2016-09-08 18:27:30

标签: sql

我有一个大约有5000万个条目的数据库,显示某一天的设备状态,简化为以下形式:

 id | status
-------------
1   | Off
1   | Off
1   | On
2   | Off
2   | Off
3   | Off
3   | Off
3   | On
...

这样每个ID都可以保证至少有2行,其中' off'状态,但不必有一个' on'状态。我试图获取一个仅列出没有“开启”的ID的列表。状态。例如,在上面的数据集中我想要一个只返回' 2'

的查询

当前查询是:

SELECT DISTINCT id FROM table 

EXCEPT

SELECT DISTINCT id FROM table WHERE status <> 'Off'

这似乎有效,但它必须遍历整个表两次,最终每次查询需要大约10-12分钟。有一个更简单的方法只用一个查询来做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以改为使用WHERE NOT EXISTS

Select Distinct Id
From   Table  A
Where Not Exists
(
    Select  *
    From    Table  B
    Where   A.Id = B.Id
    And     B.Status = 'On'
)

我还建议查看Status列上的索引。跑10-12分钟是太长了。即使有50万条记录,通过适当的索引,这样的查询也不会花费超过一秒的时间。

要为列添加索引,您可以运行它(我假设SQL Server,您的语法可能会有所不同):

Create NonClustered Index Ix_YourTable_Status On YourTable (Status Asc);

答案 1 :(得分:1)

您可以使用条件聚合。

select id
from table 
group by id
having count(case when status='On' then 1 end)=0

答案 2 :(得分:0)

您可以使用SELF JOIN的帮助..

         SELECT DISTINCT  A.Id
         FROM Table  A
             LEFT JOIN Table B ON A.Id=B.Id
         WHERE B.Status='On' 
                   AND B.Id IS NULL