SQL-在一个表中联合所有用户

SQL-在一个表中联合所有用户,sql,sql-server,unpivot,Sql,Sql Server,Unpivot,表:受欢迎 UserName FriendName -------- ---------- John Sarah Philip Ursula John Marry John Jeremy Philip Brock Khan Lemy 我要带查询的列表 John Philip Khan -------- ---------- -------- Sarah Ursula L

表:受欢迎

UserName FriendName -------- ---------- John Sarah Philip Ursula John Marry John Jeremy Philip Brock Khan Lemy 我要带查询的列表

John Philip Khan -------- ---------- -------- Sarah Ursula Lemy Marry Brock -NULL- Jeremy -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
编辑:您需要行号:

我想你可以用枢轴

这就是代码:

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语句

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

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

    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   ║
╚════════╩══════╩════════╝
您应该能够对整个表运行此操作,并获得所有可能用户名的结果,而无需键入单独的CASE语句

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

    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');

哈桑,这背后的逻辑是什么?到目前为止,你尝试了什么?@BarbarosÖzhan从表输出中可以清楚地看出这一逻辑。他想根据列中的用户名将frields列为行。@ArupRakshit,嗯,你说得对。第一行中没有任何东西将Sarah和Ursula链接起来,你需要通过行号或类似的数字进行匹配。我需要所有列表,而不仅仅是max:@HasanKaanTURAN删除max。生成好友组需要行号。我强烈建议查看PIVOT函数,让显示程序使用第一行作为列名。不要使用这样的解决方案。操作数数据类型nvarchar对于avg运算符无效。我的列具有nvarchar类型您需要为COUNT交换平均值。看起来您在动态查询中缺少分组语句。必须通过添加结束组才能将其正确地添加到组中:选择UserName、FriendName、ROW_NUMBER OVER PARTITION by UserName ORDER by FriendName作为RowNum,从流行的group by UserName中选择RowNum,FriendName xI已经向我的测试表添加了更多数据,直到添加了重复记录,我才发现任何差异。副本现在已删除。谢谢
╔════════╦══════╦════════╗
║  John  ║ Khan ║ Philip ║
╠════════╬══════╬════════╣
║ Jeremy ║ Lemy ║ Brock  ║
║ Marry  ║ NULL ║ Ursula ║
║ Sarah  ║ NULL ║ NULL   ║
╚════════╩══════╩════════╝
    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');