我在 MySQL 数据库中有两个这样的表:
Table readings:
reading_id, building_id, sub_id, reading_date
Table billings:
billing_id, building_id, sub_id, date_start, date_end
它是这样工作的: foreach couple building_id, sub_id on the readings table 我有几个阅读日期。
一些阅读日期可以用作 billings 表中的 date_start 或 date_end。我想要实现的是一个查询,它从读数表中返回一对 building_id sub_id,其中 reading_date 从未被使用过,也没有作为 date_start 或作为 building_id/sub_id 夫妇的 date_end。
由于构建表很大(>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
)
最佳答案
嗯。 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
完成您想要的工作。 SELECT DISTINCT
在使用IN
时是不必要的(尽管此代码已被EXISTS
取代)。SELECT DISTINCT
会在外部查询中产生不必要的开销。
关于 "not in"不在唯一列上的 MySql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44542583/