是否有更好的解决方案来查找表中多个已知ID的问题:
SELECT * FROM some_table WHERE id='1001' OR id='2002' OR id='3003' OR ...
我可以拥有数百个已知物品。想法?
答案 0 :(得分:23)
SELECT * FROM some_table WHERE ID IN ('1001', '1002', '1003')
如果您的已知ID来自另一个表
SELECT * FROM some_table WHERE ID IN (
SELECT KnownID FROM some_other_table WHERE someCondition
)
答案 1 :(得分:7)
第一个(天真)选项:
SELECT * FROM some_table WHERE id IN ('1001', '2002', '3003' ... )
但是,我们应该能够做得更好。当你有很多物品时,IN
非常糟糕,你提到了数百个这些物品。是什么造就了他们他们来自哪里?你能写一个返回这个列表的查询吗?如果是这样的话:
SELECT *
FROM some_table
INNER JOIN ( your query here) filter ON some_table.id=filter.id
答案 2 :(得分:3)
答案 3 :(得分:2)
在SQL中,OR的速度非常慢。
您的问题是具体细节,但根据您的要求和限制,我将使用您的ID构建一个查找表并使用EXISTS谓词:
select t.id from some_table t
where EXISTS (select * from lookup_table l where t.id = l.id)
答案 4 :(得分:0)
对于一组固定的ID,您可以这样做:
SELECT * FROM some_table WHERE id IN (1001, 2002, 3003);
对于每次更改的集合,您可能希望创建一个表来保存它们,然后查询:
SELECT * FROM some_table WHERE id IN
(SELECT id FROM selected_ids WHERE key=123);
另一种方法是使用集合 - 其语法取决于您的DBMS。
最后,始终存在这种“kludgy”方法:
SELECT * FROM some_table WHERE '|1001|2002|3003|' LIKE '%|' || id || '|%';
答案 5 :(得分:0)
在Oracle
中,我始终将id
放入TEMPORARY TABLE
以执行大量SELECT
和DML
操作:
CREATE GLOBAL TEMPORARY TABLE t_temp (id INT)
SELECT *
FROM mytable
WHERE mytable.id IN
(
SELECT id
FROM t_temp
)
您可以使用Oracle
集合类型在单个客户端 - 服务器往返中填充临时表。
答案 6 :(得分:0)
我们在为MS SQL Server 7编写的应用程序中遇到了类似的问题。虽然我不喜欢使用的解决方案,但我们还没有发现任何更好的...
据我所知,2008年存在'更好'的解决方案,但我们有Zero客户使用它:)
我们创建了一个表值用户定义函数,该函数采用逗号分隔的ID字符串,并返回一个ID表。然后,SQL读取得相当好,并且它们都不是动态的,但仍然存在恼人的双重开销:
1.客户端将ID连接到字符串
中
2. SQL Server解析字符串以创建ID表
有很多方法可以将'1,2,3,4,5'转换为ID表,但使用该功能的存储过程最终看起来像......
CREATE PROCEDURE my_road_to_hell @IDs AS VARCHAR(8000)
AS
BEGIN
SELECT
*
FROM
myTable
INNER JOIN
dbo.fn_split_list(@IDs) AS [IDs]
ON [IDs].id = myTable.id
END
答案 7 :(得分:0)
最快的是将id放在另一个表中并加入
SELECT some_table.*
FROM some_table INNER JOIN some_other_table ON some_table.id = some_other_table.id
其中some_other_table只有一个字段(ids),所有值都是唯一的