用于根据硬编码值拆分列的SQL查询

时间:2013-02-05 11:08:00

标签: sql sql-server sql-server-2008

我有一张表,例如假设这个设置

MyTable 有各种列 Id UserId ,col1,col2 col3,包括名为 Stuff 的列。< / p>

我想通过查询从MyTable输出某些列 但我想拆分'Stuff'列,以便在查询中显示2个新列

我可以定义硬编码的类别,我不确定如何在sql中表示

Categoy1 = "alpha, bravo, delta, gamma';
Categoy2 = "charlie, echo, hotel';



MyTable

ID |    UserID |      Stuff       | Other Cols....
----------------------------------------------------------
1          1          alpha
2          2          hotel
3          1          charlie
4          1          echo
5          1          gamma
6          2          bravo
7          2          delta

我希望选择查询显示

UserId  |  Category1           |  Catergory2
----------------------------------------------------------
1            alpha, gamma            charlie, echo
---------------------------------------------------------
2            bravo, delta            hotel
----------------------------------------------------------

即根据stuff列是否包含category1或category2中的项目来生成2列 基于不同的userId,类别内容可以逗号分隔为上面的

请告诉我们如何做到这一点

希望这是有道理的。

由于

2 个答案:

答案 0 :(得分:1)

您可以使用xml扩展来连接字符串,然后只需将类别硬编码到每个子查询中:

CREATE TABLE #T (ID INT, UserID INT, [Stuff] VARCHAR(300))
INSERT #T VALUES
    (1, 1, 'alpha'),
    (2, 2, 'hotel'),
    (3, 1, 'charlie'),
    (4, 1, 'echo'),
    (5, 1, 'gamma'),
    (6, 2, 'bravo'),
    (7, 2, 'delta');

SELECT  UserID,
        [Category1] = STUFF((   SELECT  ', ' + [Stuff]
                                FROM    #T t2
                                WHERE   [Stuff] IN ('alpha', 'bravo', 'delta', 'gamma')
                                AND     t.UserID = t2.UserID
                                FOR XML PATH(''), TYPE
                            ).value('.', 'NVARCHAR(MAX)'), 1, 2, ''),
        [Category2] = STUFF((   SELECT  ', ' + [Stuff]
                                FROM    #T t2
                                WHERE   [Stuff] IN ('charlie', 'echo', 'hotel')
                                AND     t.UserID = t2.UserID
                                FOR XML PATH(''), TYPE
                            ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM    (   SELECT  DISTINCT UserID
            FROM    #T
        ) t

<强> Example on SQL Fiddle

您可以在CTE(Categories)的开头定义类别,以提高可读性:

WITH Categories AS
(   SELECT  Category, Name
    FROM    (VALUES
                (1, 'alpha'), 
                (1, 'bravo'), 
                (1, 'delta'), 
                (1, 'gamma'),
                (2, 'charlie'),
                (2, 'echo'), 
                (2, 'hotel')
            ) t (Category, Name)
), Data AS
(   SELECT  UserID, [Stuff], Category
    FROM    T
            INNER JOIN Categories c
                ON c.Name = T.[Stuff]
)
SELECT  UserID,
        [Category1] = STUFF((   SELECT  ', ' + [Stuff]
                                FROM    Data t2
                                WHERE   Category = 1
                                AND     t.UserID = t2.UserID
                                FOR XML PATH(''), TYPE
                            ).value('.', 'NVARCHAR(MAX)'), 1, 2, ''),
        [Category2] = STUFF((   SELECT  ', ' + [Stuff]
                                FROM    Data t2
                                WHERE   Category = 2
                                AND     t.UserID = t2.UserID
                                FOR XML PATH(''), TYPE
                            ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM    (   SELECT  DISTINCT UserID
            FROM    T
        ) t

<强> Example on SQL Fiddle

答案 1 :(得分:1)

我的尝试,我从Stack Overflow学到的技术!...请检查:

DECLARE @Categoy1 NVARCHAR(MAX) = 'alpha, bravo, delta, gamma',
        @Categoy2 NVARCHAR(MAX) = 'charlie, echo, hotel'
SELECT 
    UserID,      
    STUFF((SELECT  ', ' + display_term
       FROM sys.dm_fts_parser('"'+ ',' + @Categoy1  + '"', 1033, NULL, 0) INNER JOIN 
            YourTable T on display_term=[Stuff]
            WHERE T.UserID= x.UserID
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') Category1,
    STUFF((SELECT  ', ' + display_term
       FROM sys.dm_fts_parser('"'+ ',' + @Categoy2  + '"', 1033, NULL, 0) INNER JOIN 
            YourTable T on display_term=[Stuff]
            WHERE T.UserID= x.UserID
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') Category2
FROM YourTable x
GROUP BY UserID