查询未在 sql 中使用 'Not IN'
Posted
技术标签:
【中文标题】查询未在 sql 中使用 \'Not IN\'【英文标题】:Query Not using 'Not IN' in sql查询未在 sql 中使用 'Not IN' 【发布时间】:2018-05-20 17:48:21 【问题描述】:如何在不使用 Not IN 的情况下编写下面的查询。由于性能原因,IN、Not in 是不可取的。
select d.cert_serial_number as str from mdm_device d where d.client_id in (:CLIENT_IDS) and d.cert_serial_number not in (Select cert_serial_number from mdm_device where client_id not in (:CLIENT_IDS))
感兴趣的表格列:
| cert_serial_number | client_id |
+--------------------+------------+
| 102 | 1073741835 |
| 102 | 1073741836 |
| 102 | 1073741837 |
| 102 | 1073741838 |
| 102 | 1073741839 |
| 103 | 1073741840 |
| 103 | 1073741831 |
+--------------------+------------+------------+
如果客户端 ID 输入为 1073741835,1073741836,则输出应为空。 如果客户端 id 输入为 1073741835,1073741836,1073741837,1073741838,1073741839 输出应为 102。
编辑: 我最终使用了以下查询: SELECT d.cert_serial_number AS str FROM mdm_device d where d.client_id in (:CLIENT_IDS) AND NOT EXISTS (SELECT 1 FROM mdm_device e WHERE d.cert_serial_number = e.cert_serial_number AND d.client_id != e.client_id)
【问题讨论】:
您所写的内容似乎应该可以使用?你的 SQL 是什么意思 【参考方案1】:假设你的查询是正确的,你可以使用not exists
:
select d.cert_serial_number as str
from mdm_device d
where d.client_id in (:CLIENT_IDS) and
not exists (select 1
from mdm_device d2
where d2.cert_serial_number = d.cert_serial_number and
d2.client_id not in (:CLIENT_IDS)
);
或者你可以使用聚合:
select d.cert_serial_number as str
from mdm_device d
group by d.cert_serial_number
having sum(d2.client_id in (:CLIENT_IDS)) = count(*);
也就是说,只退回具有这些序列号的设备,而没有其他设备。
【讨论】:
【参考方案2】:您的问题是性能方面的问题:如果您缺少有价值的索引或重要的列来满足系统的基本要求,那么任何查询都无法解决您的性能问题。
您不希望 cert_serial_number 包含在结果中的那些客户来自哪里?您是否有可能错过了一个可以极大地帮助您将这些客户证书与您的结果区分开来的专栏?
我的解决方案:我建议您回到您的要求并重新评估。我很确定其中一个会在某处生成一列,并帮助您获得具有预期性能的结果。
【讨论】:
以上是关于查询未在 sql 中使用 'Not IN'的主要内容,如果未能解决你的问题,请参考以下文章