SQL查询以选择特定列值并连接它们

SQL查询以选择特定列值并连接它们,sql,sql-server,database,sql-server-2008,tsql,Sql,Sql Server,Database,Sql Server 2008,Tsql,有人能帮我实现这个查询吗:我需要携带每个字母的值为1的所有ID: select distinct 'A', (select cast(id as varchar)+',' from letters where a=1 for xml path('')) ids from letters where a=1 union all select distinct 'B', (select cast(id as varchar)+',' from letters where b=1 for xml

有人能帮我实现这个查询吗:我需要携带每个字母的值为1的所有ID:

select distinct 'A',
(select cast(id as varchar)+',' from letters where a=1 for xml path('')) ids
 from letters where a=1
union all 
select distinct 'B',
(select cast(id as varchar)+',' from letters where b=1 for xml path('')) ids
from letters where b=1
union all
select distinct 'C',
(select cast(id as varchar)+',' from letters where c=1 for xml path('')) ids
 from letters where c=1
union all 
select distinct 'D',
(select cast(id as varchar)+',' from letters where d=1 for xml path('')) ids
from letters where D=1
union all
select distinct 'E',
(select cast(id as varchar)+',' from letters where e=1 for xml path('')) ids
 from letters where e=1
union all 
select distinct 'F',
(select cast(id as varchar)+',' from letters where f=1 for xml path('')) ids
from letters where f=1

这是一个两步过程。首先,需要将列解压到行:

SELECT  upvt.ID, Letters
FROM    T
        UNPIVOT
        (   Value
            FOR Letters IN ([A], [B], [C], [D], [E], [F])
        ) upvt
WHERE   upvt.Value = 1;
这使得:

ID  Letters
10  A
10  C
10  E
10  F
...
然后,您需要连接来自此结果的ID:'

WITH Unpivoted AS
(   SELECT  upvt.ID, Letters
    FROM    T
            UNPIVOT
            (   Value
                FOR Letters IN ([A], [B], [C], [D], [E], [F])
            ) upvt
    WHERE   upvt.Value = 1
)
SELECT  u.Letters,
        IDs = STUFF((   SELECT  ', ' + CAST(u2.ID AS VARCHAR(10))
                        FROM    Unpivoted u2
                        WHERE   u.Letters = u2.Letters
                        FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM    Unpivoted u
GROUP BY u.Letters;
其中:

Letters IDs
A       10, 20, 50
B       20, 40
C       10, 20, 30, 40, 50
D       30, 40
E       10, 50
F       10, 20, 40

这里有两个问题:首先,表未规范化,因此您确实需要首先执行额外的步骤来创建一个临时表来规范化数据:

第一步:

select id, 'A' as letter
from mytable where a=1
union
select id, 'B'
from mytable where b=1
union
select id, 'C'
from mytable where c=1
union
select id, 'D'
from mytable where d=1
union
select id, 'E'
from mytable where e=1
union
select id, 'F'
from mytable where f=1
然后需要将多个ID塞进一个字段中。您可以使用(冒充地命名为)“For XML”来实现这一点

比如:

select letter, id + ', ' as [text()] 
from 
(    
select id, 'A' as letter
from mytable where a=1
union
select id, 'B'
from mytable where b=1
union
select id, 'C'
from mytable where c=1
union
select id, 'D'
from mytable where d=1
union
select id, 'E'
from mytable where e=1
union
select id, 'F'
from mytable where f=1
) q
group by letter
for XML path(''))

我想那会有用。

看起来您需要使用SQL PIVOT\UNPIVOT,看看这是否有帮助,非常感谢。在哪里可以指定字母列的值。例如,A的列名是字母A。如何将其作为“A”而不是结果中的列名“字母A”?只需使用替换,其中显示
SELECT u.Letters
use
SELECT Letters=replace(u.Letters,'Letter_u','')
谢谢,最后一个问题。如何将其插入临时表?它不允许我这样做,因为查询使用的是“with”。请将insert放在CTE和SELECT之间-
with(…)insert表(列)SELECT