SQL Server NOT EXISTS效率

时间:2016-12-07 16:48:17

标签: sql sql-server

我有两个表CardHistory,它们具有一对多的关系:一张卡片可以有一个或多个历史记录。 Card列有CardId列,History列有CardIdStatusId列。

我想要一个SQL脚本,它选择唯一没有StatusId = 310的历史记录的卡片。

这就是我尝试过的。

SELECT 
    C.CardId 
FROM 
    Card C
WHERE NOT EXISTS (SELECT * 
                  FROM History H
                  WHERE H.CardId = C.CardId AND H.StatusId = 310)

但我想知道是否有一种有效的方式。

提前致谢。

3 个答案:

答案 0 :(得分:4)

回答关于是否有更有效方式的问题:

简短回答:不, for (DataSnapshot child : dataSnapshot.getChildren()){ Double dLat = haoRetriever.getLat(); Double dLong = haoRetriever.getLongitude(); bsHaoName = haoRetriever.getName(); Marker marker = mMap.addMarker( new MarkerOptions() .position(new LatLng(dLat, dLong)) .title(bsHaoName) .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin))); mMarkers.put("MakerId", marker.getId()); mMarkers.put("MarkerTitle", haoRetriever.getName()); mMarkers.put("MarkerDescription", haoRetriever.getDescription()); mMarkers.put("MarkerLocation", haoRetriever.getLocation()); } 最有可能是最有效的方法。

答案很长:Aaron Bertrand的文章中有许多不同方法做同样事情的基准Should I use not in, outer apply, left outer join, except, or not exists? Spoiler:not exists获胜。

我会坚持使用不存在的原始代码,但Aaron的文章有很多例子可以适应你的情况,以确认没有其他更有效的。

not exists

答案 1 :(得分:3)

你所追求的是一种“消极的联想”。这是一个没有子查询的版本:

SELECT c.CardId
FROM Card c
LEFT OUTER JOIN History h
  ON h.CardId = c.CardId
  AND h.StatusId = 310
WHERE h.CardId IS NULL;

答案 2 :(得分:1)

您的NOT EXISTS方法看似合理,但还有另一种方法。

SELECT *
FROM   Card C
WHERE  EXISTS (SELECT 1
               FROM   history H
               WHERE  H.CardId = C.CardId
               HAVING Count(CASE WHEN H.StatusId = 310 THEN 1 END) = 0) 

通过使用实时数据运行这两个查询来检查性能