TSQL Select查询,生成类似于ms access多值字段的输出

TSQL Select查询,生成类似于ms access多值字段的输出,sql,sql-server,Sql,Sql Server,我在SQL Server 2008中有一些表,例如: 主题的 TopicID: nvarchar (Primary Key) ProgID: nvarchar topic1: bit topic2: bit topic3: bit topic4: bit 主题表如下所示: TopicID ProgID topic1 topic2 topic3 topic4 topic001 prog001

我在SQL Server 2008中有一些表,例如:

主题的

 TopicID: nvarchar  (Primary Key)
 ProgID: nvarchar
 topic1: bit
 topic2: bit
 topic3: bit
 topic4: bit
主题表如下所示:

 TopicID      ProgID        topic1        topic2       topic3        topic4

 topic001     prog001         1             1             0             0
 topic002     prog002         1             0             1             1
 topic003     prog003         1             0             0             0
 topic004     prog004         1             1             1             1
程序表:

 ProgID: nvarchar  (Primary Key)
 ProgramName: nvarchar
程序表如下所示:

 ProgID         ProgramName         

 prog001        programA            
 prog002        programB
 prog003        programC
 prog004        programD
;WITH cteTopics AS (
SELECT T.ProgID
  ,STUFF((
    SELECT T1.TopicID + ','
    FROM TopicTable T1
    WHERE T1.ProgID = T.ProgID
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR (MAX)')
    ,1,0,'') [Topics]
FROM TopicTable T
GROUP BY T.ProgID)

SELECT P.ProgID, P.ProgramName, T.Topics
FROM Program P
LEFT JOIN cteTopics T ON T.ProgID = P.ProgID
我想创建一个视图以获得如下输出:

   ProgID         ProgramName          Topic

   prog001        programA             topic1,topic2
   prog002        programB             topic1,topic3,topic4
   prog003        programB             topic1
   prog004        programD             topic1,topic2,topic3,topic4
谁能帮我弄到这个吗。
谢谢。

这里会有一些额外的逗号,但您可以稍微调整代码以消除多余的逗号。这就是我目前为你准备的

CREATE Table Topic (Topic NVARCHAR(20), Programe NVARCHAR(20), Topic1 bit, Topic2 bit,Topic3 bit,Topic4 bit)
GO
INSERT INTO Topic
 VALUES 
 ('topic001','prog001',1,1,0,0),
 ('topic002','prog002',1,0,1,1),
 ('topic003','prog003',1,0,0,0),
 ('topic004','prog004',1,1,1,1)
 GO


CREATE TABLE Programe (P_ID NVARCHAR(20) , Name NVARCHAR(20))
GO
INSERT INTO Programe VALUES
 ('prog001','programA'),            
 ('prog002','programB'),
 ('prog003','programC'),
 ('prog004','programD')
 GO
视图定义

CREATE VIEW vw_ViewName
AS
 SELECT P_ID, Name, ISNULL(STUFF(L1.Topic1L, 1, 1 , '') + ', ', '') + ISNULL(STUFF(L2.Topic2L, 1, 1, '') + ', ', '') 
                                    +  ISNULL( STUFF(L3.Topic3L, 1, 1, '')+ ', ', '') + ISNULL(STUFF(L4.Topic4L, 1, 1, '')+ ', ', '')  AS Topics
 FROM Programe P CROSS APPLY (
                            SELECT ' ' + CASE WHEN Topic1 = 1 THEN 'Topic1' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L1(Topic1L)
                CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic2 = 1 THEN 'Topic2' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L2(Topic2L)
               CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic3 = 1 THEN 'Topic3' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L3(Topic3L)
               CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic4= 1 THEN 'Topic4' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L4(Topic4L)
结果集

P_ID    Name        Topics
prog001 programA    Topic1,  Topic2, 
prog002 programB    Topic1,  Topic3,  Topic4, 
prog003 programC    Topic1, 
prog004 programD    Topic1,  Topic2,  Topic3,  Topic4, 

这里会有一些额外的逗号,但是可以稍微调整代码以消除额外的逗号。这就是我目前为你准备的

CREATE Table Topic (Topic NVARCHAR(20), Programe NVARCHAR(20), Topic1 bit, Topic2 bit,Topic3 bit,Topic4 bit)
GO
INSERT INTO Topic
 VALUES 
 ('topic001','prog001',1,1,0,0),
 ('topic002','prog002',1,0,1,1),
 ('topic003','prog003',1,0,0,0),
 ('topic004','prog004',1,1,1,1)
 GO


CREATE TABLE Programe (P_ID NVARCHAR(20) , Name NVARCHAR(20))
GO
INSERT INTO Programe VALUES
 ('prog001','programA'),            
 ('prog002','programB'),
 ('prog003','programC'),
 ('prog004','programD')
 GO
视图定义

CREATE VIEW vw_ViewName
AS
 SELECT P_ID, Name, ISNULL(STUFF(L1.Topic1L, 1, 1 , '') + ', ', '') + ISNULL(STUFF(L2.Topic2L, 1, 1, '') + ', ', '') 
                                    +  ISNULL( STUFF(L3.Topic3L, 1, 1, '')+ ', ', '') + ISNULL(STUFF(L4.Topic4L, 1, 1, '')+ ', ', '')  AS Topics
 FROM Programe P CROSS APPLY (
                            SELECT ' ' + CASE WHEN Topic1 = 1 THEN 'Topic1' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L1(Topic1L)
                CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic2 = 1 THEN 'Topic2' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L2(Topic2L)
               CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic3 = 1 THEN 'Topic3' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L3(Topic3L)
               CROSS APPLY (
                            SELECT ', ' + CASE WHEN Topic4= 1 THEN 'Topic4' ELSE NULL END [text()]
                            FROM Topic
                            WHERE Programe = P.P_ID
                            FOR XML PATH('')
                            )L4(Topic4L)
结果集

P_ID    Name        Topics
prog001 programA    Topic1,  Topic2, 
prog002 programB    Topic1,  Topic3,  Topic4, 
prog003 programC    Topic1, 
prog004 programD    Topic1,  Topic2,  Topic3,  Topic4, 

它看起来是这样的:

 ProgID         ProgramName         

 prog001        programA            
 prog002        programB
 prog003        programC
 prog004        programD
;WITH cteTopics AS (
SELECT T.ProgID
  ,STUFF((
    SELECT T1.TopicID + ','
    FROM TopicTable T1
    WHERE T1.ProgID = T.ProgID
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR (MAX)')
    ,1,0,'') [Topics]
FROM TopicTable T
GROUP BY T.ProgID)

SELECT P.ProgID, P.ProgramName, T.Topics
FROM Program P
LEFT JOIN cteTopics T ON T.ProgID = P.ProgID

它看起来是这样的:

 ProgID         ProgramName         

 prog001        programA            
 prog002        programB
 prog003        programC
 prog004        programD
;WITH cteTopics AS (
SELECT T.ProgID
  ,STUFF((
    SELECT T1.TopicID + ','
    FROM TopicTable T1
    WHERE T1.ProgID = T.ProgID
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR (MAX)')
    ,1,0,'') [Topics]
FROM TopicTable T
GROUP BY T.ProgID)

SELECT P.ProgID, P.ProgramName, T.Topics
FROM Program P
LEFT JOIN cteTopics T ON T.ProgID = P.ProgID

显示一些数据和预期输出。请看这里:@YuriyGalanter。这个链接很好,但它并不完全是我要找的。我希望列名作为列值返回,然后为每个ProgIDShow显示一些数据和预期的输出进行聚合。请看这里:@YuriyGalanter。这个链接很好,但它并不完全是我要找的。我希望列名作为列值返回,然后为每个progid聚合它们视图完全按照我的要求工作,但每次打开视图设计时都会收到此语法错误消息。错误消息显示:“(”附近的WHERE子句出错。无法分析查询文本。当我单击“确定”按钮时,它会消失,并且执行时没有任何问题。我不明白为什么会出现此错误消息。是因为(Topic1L)、(Topic2L)、(Topic3L)、(Topic4L)吗。我创建了表,然后执行了view语句,效果很好。请仔细检查您的语法,可能是在您将此查询中的表名替换为实际缺少的表名时。如果您创建了我在回答中创建的表,然后执行查询,则不会抛出错误,这表示语法正确。只要仔细阅读代码并尝试遵循逻辑,我相信它会起作用:)作为视图执行时,我会收到错误消息,但作为查询执行时,我不会收到任何错误消息。查询设计不会在查询中显示任何错误。我尝试了大卫给出的答案,得到了相同的错误信息。是否与路径(“”)命令有关。视图运行得很好,但我只是好奇为什么每次在设计模式下打开视图时都会收到错误消息。我刚刚创建了一个视图并从中选择了数据,工作正常。视图完全按照我的要求工作,但每次打开视图设计时都会收到此语法错误消息。错误消息显示:“(”附近的WHERE子句出错。无法分析查询文本。当我单击“确定”按钮时,它会消失,并且执行时没有任何问题。我不明白为什么会出现此错误消息。是因为(Topic1L)、(Topic2L)、(Topic3L)、(Topic4L)吗。我创建了表,然后执行了view语句,效果很好。请仔细检查您的语法,可能是在您将此查询中的表名替换为实际缺少的表名时。如果您创建了我在回答中创建的表,然后执行查询,则不会抛出错误,这表示语法正确。只要仔细阅读代码并尝试遵循逻辑,我相信它会起作用:)作为视图执行时,我会收到错误消息,但作为查询执行时,我不会收到任何错误消息。查询设计不会在查询中显示任何错误。我尝试了大卫给出的答案,得到了相同的错误信息。是否与路径(“”)命令有关。视图运行得很好,但我只是想知道为什么每次在设计模式下打开视图时都会收到错误消息。我刚刚创建了一个视图并从中选择了数据,工作正常。