(编辑以添加上下文信息)
我在表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
答案 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;