简体   繁体   English

T-SQL PIVOT:一行到列名,另一行为值

[英]T-SQL PIVOT: One row to column name and the other to value

I am using SQL Server 2008. 我正在使用SQL Server 2008。

I have two tables 我有两张桌子

  1. User ( UserID, Name, Link ) UserUserID, Name, Link
  2. UserNotes ( NoteID, UserID, Title, Description ) UserNotesNoteID, UserID, Title, Description

This is the sample data structure. 这是示例数据结构。

INSERT INTO [User]
    ([UserID], [Name], [Link])
VALUES
    (1, 'John', 'L1'),
    (2, 'Steve', 'L234');

INSERT INTO [UserNotes]
    ([NoteID], [UserID], [Title], [Description])
VALUES
    (1, 1, 'AboutJohn', 'This is about john'),
    (2, 1, 'John Work', 'This is where John work'),
    (3, 1, 'John Education', 'This is the uni where John go'),
    (4, 2, 'Steve Note1', 'Des1 about Steve'),
    (5, 2, 'Steve Note2', 'Des2 about Steve');

Here is SQL Fiddle 这是SQL小提琴

I want to create view ( User_view ) as follows and when I execute this command the output should be as follows. 我想按如下方式创建视图( User_view ),当我执行此命令时,输出应如下所示。

SELECT * FROM User_view WHERE UserID IN (1)

UserID    Name   AboutJOhn              JohnWork                  JohnEducation
1         John   This is about john     This is where Johnwork    This is the uni where John go

Title column of child table should become column name and Description should become value of that column and we do not know how many rows we will have. 子表的Title列应该成为列名, Description应该成为该列的值,我们不知道我们将拥有多少行。 I am aware of the issue when we select two users and which name to use column name. 当我们选择两个用户以及使用列名称的名称时,我知道这个问题。 In that case we can use (Note1, Note2, Note3, etc for multiple User), otherwise use title field as Column name. 在这种情况下,我们可以使用(Note1,Note2,Note3等多个用户),否则使用title字段作为列名。 Is it possible to do so? 有可能这样做吗? Cheers! 干杯!

CREATE VIEW User_view
AS
SELECT UserID, Name, [AboutJohn], [John Work], [John Education]
FROM 
 (
  SELECT n.UserID, u.Name, n.Title, n.Description
  FROM [User] u JOIN UserNotes n ON u.UserID = n.UserID
  WHERE u.UserID IN (1)
  ) a
PIVOT
 (
  MAX(Description)
  FOR Title IN ([AboutJohn], [John Work], [John Education])
  ) b

this is not a view.. This is a procedure which will return the result as you want 这不是一个视图..这是一个将根据需要返回结果的过程

you can call it as 你可以称之为

proc_UserNotes 1 proc_UserNotes 1
proc_UserNotes 2 proc_UserNotes 2

etc 等等

CREATE procedure proc_UserNotes (@UserID int)
as
begin

DECLARE @cols AS NVARCHAR(MAX),
        @cols_WITH_MAX AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

select @cols_WITH_MAX = STUFF((SELECT distinct ',MAX(' 
              + QUOTENAME(Title) +') AS ' + QUOTENAME(Title)
                    from [UserNotes] where UserID =@UserID
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Title) 
                    from [UserNotes] where UserID =@UserID
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')        


set @query = 'SELECT [UserID], '+ @cols_WITH_MAX +' FROM(
             SELECT [UserID], ' + @cols + ' from 
            (
            SELECT * FROM 
            [UserNotes]   where UserID ='+cast(@UserID as varchar(20)) +'
            )X

            pivot 
            (
                MAX([Description])
                for [Title] in (' + @cols + ')
            ) p )a GROUP BY [UserID]'


print(@query)
execute(@query)

end 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM