SQL - 将所有用户合二为一 Table

SQL - Union All Users in One Table

Table : 热门

用户名朋友名
------------------
约翰莎拉
菲利普厄休拉
约翰玛丽
约翰杰里米
菲利普布罗克
汗莱米

我想要带有查询的列表;

约翰·菲利普·汗
------ ---------- ------
莎拉·乌苏拉·莱米
嫁给布洛克 -NULL-
杰里米 -NULL- -NULL-

我有 100 多个用户名...帮我列出 SQL 查询 (MSSQL)

用例

select max(case when UserName='John' then fieldname end) as john,
       max(case when UserName='Philip' then fieldname end) as Philip,
       max(case when UserName='Khan' then fieldname end) as Khan
        from table_name

编辑:您需要row_number()

select max(case when username = 'John' then friendname end) as [John],
       max(case when username = 'Philip' then friendname end) as [Philip],
       max(case when username = 'Khan' then friendname end) as [Khan],
       . . . 
from (select t.*,
             row_number() over (partition by username order by friendname) as seq
      from table t
     ) t
group by seq;

我认为你可以使用 pivot https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017

-- Pivot table with one row and five columns  
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,   
[0], [1], [2], [3], [4]  
FROM  
(SELECT DaysToManufacture, StandardCost   
FROM Production.Product) AS SourceTable  
PIVOT  
(  
AVG(StandardCost)  
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])  
) AS PivotTable;  

即代码:

if OBJECT_ID('userName') is not null drop table userName;

create table userName (fiiduserName int identity(1,1), fcName varchar(20), 
fcFrienlyName varchar(20));

insert into userName(fcName, fcFrienlyName)values ('John', 'Sarah');
insert into userName(fcName, fcFrienlyName)values ('Philip', 'Ursula');
insert into userName(fcName, fcFrienlyName)values ('John', 'Marry');
insert into userName(fcName, fcFrienlyName)values ('John', 'Jeremy');
insert into userName(fcName, fcFrienlyName)values ('Philip', 'Brock');
insert into userName(fcName, fcFrienlyName)values ('Khan', 'Lemy');

declare @Nombres varchar(max);
declare @select varchar(max);

select @Nombres = COALESCE(@Nombres + ',', '') + '[' + fcName + ']'
from userName
group by fcName;

select @select  = 'SELECT fiiduserName, ' +  @Nombres + '
FROM  
(SELECT fiiduserName, fcName, fcFrienlyName
    FROM userName) AS SourceTable  
PIVOT  
(  
MIN(fcFrienlyName)  
FOR fcName IN (' + @Nombres + ')
) AS PivotTable; ' 

exec (@select);

drop table userName;

如果您有“100 多个用户名”,您会希望它是动态的,这样您就不必为每个用户名键入特定的 CASE 语句。

此外,您也不希望每次向 table 添加新用户名时都必须更新脚本。

下面的脚本将动态检索所有不同的用户名,并为他们创建一个包含所有朋友行的列。

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

    SET @cols = STUFF((SELECT distinct ',MAX(CASE WHEN UserName = ''' 
                        + p.UserName + ''' THEN FriendName END) AS ' 
                        + QUOTENAME(p.UserName) FROM Popular p
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')

    SET @query = 'SELECT ' + @cols + ' FROM 
                (SELECT UserName, FriendName
                    ,ROW_NUMBER() OVER (PARTITION BY UserName ORDER BY FriendName) AS RowNum
                    FROM Popular GROUP BY USERNAME, FRIENDNAME
                ) x
                GROUP BY RowNum'

    EXECUTE(@query);

我上面的输出如下所示;

╔════════╦══════╦════════╗
║  John  ║ Khan ║ Philip ║
╠════════╬══════╬════════╣
║ Jeremy ║ Lemy ║ Brock  ║
║ Marry  ║ NULL ║ Ursula ║
║ Sarah  ║ NULL ║ NULL   ║
╚════════╩══════╩════════╝

您应该能够 运行 针对整个 table 并获得所有可能的用户名的结果,而无需键入单独的 CASE 语句。

对于任何想要测试的人,这里是测试 table 和数据脚本;

    IF EXISTS ( SELECT *
                FROM INFORMATION_SCHEMA.TABLES
                WHERE TABLE_NAME = 'Popular'
                AND TABLE_SCHEMA = 'dbo'
                AND TABLE_TYPE = 'TABLE')
    DROP TABLE [dbo].[Popular];
    GO

    CREATE TABLE [dbo].[Popular]
    (
    UserName VARCHAR(20),
    FriendName VARCHAR(20)
    );
    GO

    INSERT INTO [dbo].[Popular] (UserName,FriendName) VALUES
    ('John','Sarah'),
    ('Philip','Ursula'),
    ('John','Marry'),
    ('John','Jeremy'),
    ('Philip','Brock'),
    ('Khan','Lemy');