SQL:获取不在另一个CSV列表中的CSV列表(或字段)中的PK ID

时间:2019-02-20 01:36:41

标签: sql sql-server csv

(编辑以添加上下文信息)

我在表A中有2个字段,其中包含另外2个表中记录ID的CSV列表。 “ USERS”字段包含USERS_TABLE中记录的CSV列表; “ CONTACTS”字段包含CONTACTS_TABLE中记录的CSV列表:

USERS_FIELD:“ 1,2,3,4,5,6”

CONTACTS_FIELD:“ 2,4,6,8”

我想找到所有在USERS_FIELD列表中但不在CONTACTS_FIELD列表中的记录。在这种情况下,我想要记录1,3,5。列表的范围从1个ID到数百个。

该解决方案必须在查询的WHERE子句中运行。我的环境是COTS产品中的基于VBScript的脚本语言:在Microsoft Windows Server和SQL Server 2012上运行的MicroFocus / Serena SBM。该脚本语言允许我指定WHERE和ORDERBY子句,并且它执行查询并返回结果。产品内置了多个以CSV格式存储的记录ID。我对此无能为力,也无法创建SQL临时表或定义SQL函数。主机编写语言的实现删除了数组和“拆分”功能。虽然我可以将CSV解析为Dictionary对象,但是要对其中的每一个都有数百个元素进行迭代并不是很快。这一切都在最终用户等待网页完成时发生。同样,这就是产品的设计方式。

我可以使用UNION类型的运算符执行以下操作吗?

Select ID from USERS_TABLE Where ID in USERS_FIELD
MINUS 
Select ID from CONTACTS_TABLE Where ID in CONTACTS_FIELD 

1 个答案:

答案 0 :(得分:0)

不确定我是否遵循需要在WHERE子句中运行的解决方案的要求。如果您使用的是SQL Server 2017,则可以利用STRING_SPLIT(在SQL Server 2016中也可用)和STRING_AGG函数。

DROP TABLE IF EXISTS #A;
CREATE TABLE #A (id INT PRIMARY KEY IDENTITY, users VARCHAR(MAX), contacts VARCHAR(MAX));
INSERT INTO #A (users, contacts) 
VALUES 
    ('1,2,3,4,5,6', '2,4,6,8'),
    ('3,5,6', '4,6,9'),
    ('2,4,7,9', '2,4,9');

SELECT 
    A.id,
    A.users,
    A.contacts,
    STRING_AGG(B.value, ',') intersection
FROM #A A 
CROSS APPLY STRING_SPLIT(users, ',') B
WHERE   NOT EXISTS (SELECT * FROM STRING_SPLIT(A.contacts, ',') X1 WHERE B.value = X1.value) -- where user is not in contacts
GROUP BY
    A.id,
    A.users,
    A.contacts;