首页 > 解决方案 > 如何在 SQL 的 IN 语句中使用逗号分隔值列?

问题描述

我有下表,相关列包含使用 id 列引用自身的 id

id  name    relate
1   James   1
2   John    1-2
3   Bob     1-2-3

我正在处理下面的查询,但没有工作

SELECT id, name, (
                   SELECT zrelate =
                    Stuff
                        (
                            (
                                SELECT ', ' + name AS [text()] FROM
                                    (
                                        SELECT name
                                        FROM myTable
                                        WHERE id IN REPLACE(relate,'-',',')
                                    ) x
                                For XML PATH ('')
                            ),1,1,''
                        )
                 ) 'zrelate'
FROM myTable

预期的输出是

id  name    zrelate
1   James   James
2   John    James,John
3   Bob     James,John,Bob

这是一个来自未知数据库的设计糟糕的表,但当前加载到 SQL 2012 中。目标是为用户提取数据并出于明显的原因删除该表。

标签: sqlsql-server

解决方案


修复设计,修复问题。相反,您应该有 2 张桌子,一张与人有关,另一张与关系有关。

这为您提供了这样的设计:

CREATE TABLE dbo.Person (id int NOT NULL PRIMARY KEY,
                         [name] varchar(5));
GO
CREATE TABLE dbo.Relation(ParentID int, ChildId int);

ALTER TABLE dbo.Relation ADD CONSTRAINT FK_ParentPerson FOREIGN KEY (ParentID) REFERENCES dbo.Person(id);
ALTER TABLE dbo.Relation ADD CONSTRAINT FK_ChildPerson FOREIGN KEY (ChildID) REFERENCES dbo.Person(id);

您的数据将如下所示:

INSERT INTO dbo.Person (id, [name])
VALUES (1,'James'),
       (2,'John'),
       (3,'Bob')

INSERT INTO dbo.Relation
VALUES(1,1),
      (2,1),
      (2,1),
      (3,1),
      (3,2),
      (3,2);

然后,最后,你得到一个像这样的标准化数据集:

SELECT P.id,
       P.name,
       C.name
FROM dbo.Person P
     JOIN dbo.Relation R ON P.id = R.ParentID
     JOIN dbo.Person C ON R.ChildId = C.id;

推荐阅读