2017-06-14 49 views
1

我有两个表像这样的一个MySQL数据库:MySQL查询与“不是”不是唯一的列

Table readings: 
reading_id, building_id, sub_id, reading_date 

Table billings: 
billing_id, building_id, sub_id, date_start, date_end 

这就是它是如何工作的: 的foreach夫妇building_id,sub_id上读数表我有几个阅读日期。

这些阅读日期中的一些可以用作帐单表中的date_start或date_end。我想实现的是一个单一的查询,它返回reading_date从未被使用过的building_id sub_id,或者作为date_start和date_end来为building_id/sub_id这对夫妇返回。

由于建筑表格很大(> 5k行),我必须同时检查所有建筑物,所以我希望以最快的方式做到这一点,而不是进行5k查询。

我试过这个查询,但它不工作:

SELECT DISTINCT a.reading_id, a.sub_id 
FROM readings AS a 
    LEFT JOIN billings AS b ON b.building_id=a.building_id 
          AND b.sub_id=a.sub_id 
WHERE reading_date NOT IN (SELECT DISTINCT date_start 
          FROM billings 
          WHERE b.building_id=a.building_id 
           AND b.sub_id=a.sub_id 
          ) 
AND reading_date NOT IN (SELECT DISTINCT date_end 
         FROM billings 
         WHERE b.building_id=a.building_id 
          AND b.sub_id=a.sub_id 
         ) 

回答

0

嗯。 NOT EXISTS通常比NOT IN快:

SELECT r.reading_id, r.sub_id 
FROM readings r 
WHERE NOT EXISTS (SELECT 1 
        FROM billings b 
        WHERE b.building_id = r.building_id AND 
         b.sub_id = r.sub_id AND 
         b.date_start = r.reading_date 
       ) AND 
     NOT EXISTS (SELECT 1 
        FROM billings b 
        WHERE b.building_id = r.building_id AND 
         b.sub_id = r.sub_id AND 
         b.date_end = r.reading_date 
       ); 

出于性能考虑,你希望两个指标:billings(building_id, sub_id, date_start)billings(building_id, sub_id, date_end)

注:

  • 在外部查询的JOIN是不必要的。 NOT IN做你想要的工作。
  • 使用IN时不需要SELECT DISTINCT(尽管此代码已由EXISTS取代)。
  • SELECT DISTINCT在外部查询中引起不必要的开销。
+0

太棒了!它像一个魅力,感谢! –