【问题标题】:SQL : get PK IDs that are in a CSV list (or field) that aren't in another CSV listSQL:获取不在另一个 CSV 列表中的 CSV 列表(或字段)中的 PK ID
【发布时间】:2019-02-20 01:36:41
【问题描述】:

(已编辑以添加有关上下文的信息)

我在表 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 到数百个 ID。

解决方案必须在查询的 WHERE 子句中运行。我的环境是 COTS 产品中基于 VBScript 的脚本语言:MicroFocus/Serena SBM 在 MS Windows Server 和 SQL Server 2012 上运行。脚本语言允许我指定 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 

【问题讨论】:

  • 修复你的数据模型!不要将列表存储为字符串。
  • 您使用的是哪个版本的 SQL Server?
  • @GordonLinoff。抱歉,环境是 COTS(商业现货)产品。重新设计产品不是我的工作。

标签: sql sql-server csv


【解决方案1】:

不确定我是否遵循需要在 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;

【讨论】:

  • 这可能有效,但如前所述:解决方案必须在查询的 WHERE 子句中运行。
猜你喜欢
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2020-10-09
  • 1970-01-01
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多