SQL Server以所需格式化方式输出

时间:2017-07-23 11:20:46

标签: sql sql-server

我有两个表,tblNametblCode

tblName

CREATE TABLE [dbo].[TblName]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,

    CONSTRAINT [PK_TblName] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]

enter image description here

tblCode

CREATE TABLE [dbo].[tblCode]
(
    [NameId] [int] NULL,
    [Code] [varchar](50) NULL,
    [Value] [varchar](50) NULL
) ON [PRIMARY]

enter image description here

代码:

INSERT INTO [dbo].[TblName]
   ([Name])
VALUES
   ('Rahul'),
   ('Rohit'),
   ('John'),
   ('David'),
   ('Stephen')
   GO

INSERT INTO [dbo].[tblCode] ([NameId], [Code], [Value])
VALUES (1, 'DEL', 'Delivery'),
       (1, 'DEL', 'Deployment'),
       (2, 'REL', 'Release Management'),
       (3, 'REL', 'Release Management'),
       (4, 'TEST', 'Testing'),
       (4, 'TEST', 'Final Testing')     

我正在尝试编写一个查询来获取tblCode中包含Code和Value的所有Name。例如,我在TblCode中存在NameId 1,其中包含Code' DEL'和价值作为交付'和'部署'。类似地,我在tblCode中具有NameId 2,3和4,具有相同或不同的Code和Value。所以我试图以这样的方式获得输出,如果在tblCode中存在具有相同代码的相同名称,那么它应该具有Name和逗号分隔值的行,如下面所需的输出所示。

enter image description here

这是我正在使用的查询,但它没有提供我正在寻找的输出。

 SELECT  
     N.Name,                
     CASE 
        WHEN C.Code = 'DEL' 
           THEN C.Value 
        ELSE '' 
     END As 'CodeValue'     
 FROM 
     TblName N
 INNER JOIN 
     tblCode C ON N.Id = C.NameId
 WHERE
     C.NameId = 1 AND C.Code IN ('DEL', 'REL', 'TEST')

2 个答案:

答案 0 :(得分:2)

这是一种方法:

;WITH CTE AS
(
SELECT DISTINCT
        [NameId]
       ,[Code]
       ,(
            SELECT STUFF(
                (SELECT ',' + Value
                FROM dbo.tblCode t1
                WHERE t0.Code = t1.Code
                AND t0.NameId = t1.NameId
                FOR XML PATH(''))
                , 1, 1, '')
        ) AS CodeValue
FROM dbo.tblCode t0
)

SELECT  Name, CodeValue
FROM tblName 
INNER JOIN CTE ON Id = CTE.NameId
ORDER BY Id

结果:

Name    CodeValue
Rahul   Delivery,Deployment
Rohit   Release Management
John    Release Management
David   Testing,Final Testing

阅读this SO post以获取有关如何使用STUFF和FOR XML从多行创建连接字符串的说明。

You can see a live demo on rextester.

答案 1 :(得分:2)

http://sqlfiddle.com/#!6/bdca78/11/0

CREATE TABLE tblName (id INTEGER, name VARCHAR(255));

INSERT INTO tblName VALUES(1, 'Rahul');
INSERT INTO tblName VALUES(2, 'Rohit');
INSERT INTO tblName VALUES(3, 'John');
INSERT INTO tblName VALUES(4, 'David');
INSERT INTO tblName VALUES(5, 'Steven');

CREATE TABLE tblCode(nameId INTEGER, code VARCHAR(255), value VARCHAR(255));

INSERT INTO tblCode VALUES(1, 'DEL', 'Delivery');
INSERT INTO tblCode VALUES(1, 'DEL', 'Development');
INSERT INTO tblCode VALUES(2, 'REL', 'Release Management');
INSERT INTO tblCode VALUES(3, 'REL', 'Release Management');
INSERT INTO tblCode VALUES(4, 'TEST', 'Testing');
INSERT INTO tblCode VALUES(4, 'TEST', 'Final Testing');

SELECT name,
       codeValue
FROM
(SELECT tblName.name AS name,
       STUFF((SELECT  ',' + tblCode.value 
              FROM tblCode
              WHERE tblCode.nameId = tblName.id 
              FOR XML PATH('')), 1 ,1, '') AS codeValue
FROM tblName) inline_view
WHERE codeValue IS NOT NULL;

修改

ZoharPeled的解决方案是正确的。此解决方案返回name和逗号分隔的value列表,但不考虑code

Zohar汇总valuecode个列表,我认为这是必需的。 OP,如果目标是按namecode进行汇总,则输出中包含code会使结果集更有意义。

以下链接显示了区别,首先是我的SQL语句,然后是Zohar的。

我的SQL:http://sqlfiddle.com/#!6/94fd0/1/0 Zohar的SQL:http://sqlfiddle.com/#!6/94fd0/2/0