"not in"不在唯一列上的 MySql 查询

标签 mysql sql

我在 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/

相关文章:

Java - 小程序异常

mysql - 缩短嵌套 SQL 查询

php - 将日期插入 MySQL 时遇到问题

sql - 基于来自 SQL 的字符串中的数值排序

mysql - 如何使用联接根据特定条件从表中仅选择不同的结果

python - Django 找不到 MySQLdb python 模块

javascript - 从 MySQL 数据库获取数据并添加到列表(NodeJS)

php - 显示多连接查询的结果

sql - 从 SQL 中的多个数据库中选择 COUNT()

sql - 删除重复行(不要删除所有重复行)