SQL Read Where IN(来自 .TXT 文件的长列表)

use*_*168 8 sql where-clause where-in

我有一长串大约 5000 多个 ID(数字)。

ID
4
5
6
9
10
14
62
63
655
656
657
658
659
661
662
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法调用从 txt 文件中读取 ID 而不是在查询中输入所有 5000?

例子

SELECT count(*) from table where ID in (file1.txt)
Run Code Online (Sandbox Code Playgroud)

zed*_*xus 4

您有几种选择,其中一种是我推荐的。

选项1

在数据库中创建一个表,如下所示:

create table ID_Comparer (
    ID int primary key
);
Run Code Online (Sandbox Code Playgroud)

使用您选择的编程语言,清空表,然后加载您最终想要在此表中查询的 5000 多个 ID。

然后,编写以下查询之一来提取所需的数据:

select *
from main_table m
where exists (
    select 1 from ID_Comparer where ID = m.ID
)
Run Code Online (Sandbox Code Playgroud)

或者

select *
from main_table m
inner join ID_Comparer c on m.ID = c.ID
Run Code Online (Sandbox Code Playgroud)

由于 ID_Comparer 和(假设)main_table 的 ID 是索引/键控的,因此匹配应该相对较快。

选项1修改

此选项与上面的选项类似,但对并发性有所帮助。这意味着,如果应用程序 1 想要同时比较 2000 个 ID,而应用程序 2 想要同时与主表比较 5000 个 ID,则您不希望从比较表中删除数据。所以,稍微改变一下桌子。

create table ID_Comparer (
    ID int primary key,
    token char(32), -- index this
    entered date default current_date() -- use the syntax of your DB
);
Run Code Online (Sandbox Code Playgroud)

然后,使用您最喜欢的编程语言创建 GUID。将所有 ID 和相同的 GUID 加载到表中,如下所示:

1, 7089e5eced2f408eac8b390d2e891df5
2, 7089e5eced2f408eac8b390d2e891df5
...
Run Code Online (Sandbox Code Playgroud)

另一个执行相同操作的进程将使用 GUID 加载自己的 ID

2412, 96d9d6aa6b8d49ada44af5a99e6edf56
9434, 96d9d6aa6b8d49ada44af5a99e6edf56
...
Run Code Online (Sandbox Code Playgroud)

现在,您的选择:

select *
from main_table m
where exists (
    select 1 from ID_Comparer where ID = m.ID and token = '<your guid>'
)
Run Code Online (Sandbox Code Playgroud)

或者

select *
from main_table m
inner join ID_Comparer c on m.ID = c.ID and token = '<your guid>'
Run Code Online (Sandbox Code Playgroud)

收到数据后,请务必执行此操作delete from ID_Comparer where token = '<your guid>'- 这将是很好的清理工作

您可以创建一个夜间任务来删除所有超过 2 天的数据或一些此类数据以进行额外的内务处理。

由于 ID_Comparer 和(假设)main_table 的 ID 是索引/键控的,因此即使 GUID 是附加键控查找,匹配也应该相对较快。

选项2

您可以创建一个大型 SQL 查询,而不是创建表,如下所示:

select * from main_table where id = <first id>
union select * from main_table where id = <second id>
union select * from main_table where id = <third id>
...
Run Code Online (Sandbox Code Playgroud)

或者

select * from main_table where id IN (<first 5 ids>)
union select * from main_table where id IN (<next 5 ids>)
union select * from main_table where id IN (<next 5 ids>)
...
Run Code Online (Sandbox Code Playgroud)

如果性能可以接受,并且您觉得像选项 1 那样创建新表不合适,您可以尝试其中一种方法。

(假设)main_table 的 ID 是索引/键控的,单独匹配可能会导致更快的查询,而不是与一长串逗号分隔值匹配。这是一个猜测。您必须查看查询计划并针对测试用例运行它。

选择哪个选项?

测试这些选项应该很快。我建议根据您的数据库引擎和表的大小尝试所有这些选项,看看哪一个最适合您的用例。