Sql select 重复行多列
Sql select duplicate rows multiple columns
我想要一个查询,其中 return 每个 ComuterName
一行。该行应包含查询的应用程序及其版本。我当前的查询:
SELECT DISTINCT
dbo.v_R_System.Name0 [ComputerName],
dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 [App],
dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0
FROM
dbo.v_R_System
INNER JOIN dbo.v_GS_ADD_REMOVE_PROGRAMS
ON dbo.v_R_System.ResourceID = dbo.v_GS_ADD_REMOVE_PROGRAMS.ResourceID
INNER JOIN dbo.v_R_User
ON dbo.v_R_System.User_Name0 = dbo.v_R_User.User_Name0
INNER JOIN dbo.v_GS_COMPUTER_SYSTEM
ON dbo.v_R_System.Name0 = dbo.v_GS_COMPUTER_SYSTEM.Name0
INNER JOIN v_GS_PC_BIOS
ON dbo.v_R_System.ResourceID = dbo.v_GS_PC_BIOS.ResourceID
WHERE
dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%'
OR dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%'
OR dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%'
返回这个:
╔══════════════╦════════════════════╦═════════╗
║ ComputerName ║ App ║ Version ║
╠══════════════╬════════════════════╬═════════╣
║ PC1 ║ MS Word ║ 12 ║
║ PC1 ║ Adobe Reader ║ 10.0.10 ║
║ PC1 ║ Adobe Flash Player ║ 15.1 ║
║ PC2 ║ MS Word ║ 15 ║
║ PC2 ║ Adobe Reader ║ 11.0.07 ║
║ PC2 ║ Adobe Flash Player ║ 16 ║
╚══════════════╩════════════════════╩═════════╝
我想return这种方式的信息:
╔══════════════╦═════════╦═════════╦══════════════╦═════════╦════════════════════╦═════════╗
║ ComputerName ║ App1 ║ App1Ver ║ App2 ║ App2Ver ║ App3 ║ App3Ver ║
╠══════════════╬═════════╬═════════╬══════════════╬═════════╬════════════════════╬═════════╣
║ PC1 ║ MS Word ║ 12 ║ Adobe Reader ║ 10.0.10 ║ Adobe Flash Player ║ 15.1 ║
║ PC2 ║ MS Word ║ 15 ║ Adobe Reader ║ 11.0.07 ║ Adobe Flash Player ║ 16 ║
╚══════════════╩═════════╩═════════╩══════════════╩═════════╩════════════════════╩═════════╝
此数据库存储在 SQL Server 2008 R2 上。
提前致谢。
你可以使用 case based aggregation
,这里的 like
还有一个问题,因为你使用的是 % 通配符,索引不会被使用,并且在大数据集上会变慢
最好使用组 ID 列并在应用程序名称和组之间建立映射 table,并在查询中使用组 ID。
SELECT
dbo.v_R_System.Name0 [ComputerName],
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%' then 'MS Word' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App1Ver
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%' then 'Adobe Reader' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App2Ver
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%' then 'Flash Player' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App3Ver
FROM
dbo.v_R_System
INNER JOIN dbo.v_GS_ADD_REMOVE_PROGRAMS
ON dbo.v_R_System.ResourceID = dbo.v_GS_ADD_REMOVE_PROGRAMS.ResourceID
INNER JOIN dbo.v_R_User
ON dbo.v_R_System.User_Name0 = dbo.v_R_User.User_Name0
INNER JOIN dbo.v_GS_COMPUTER_SYSTEM
ON dbo.v_R_System.Name0 = dbo.v_GS_COMPUTER_SYSTEM.Name0
INNER JOIN v_GS_PC_BIOS
ON dbo.v_R_System.ResourceID = dbo.v_GS_PC_BIOS.ResourceID
group by dbo.v_R_System.Name0
我想要一个查询,其中 return 每个 ComuterName
一行。该行应包含查询的应用程序及其版本。我当前的查询:
SELECT DISTINCT
dbo.v_R_System.Name0 [ComputerName],
dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 [App],
dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0
FROM
dbo.v_R_System
INNER JOIN dbo.v_GS_ADD_REMOVE_PROGRAMS
ON dbo.v_R_System.ResourceID = dbo.v_GS_ADD_REMOVE_PROGRAMS.ResourceID
INNER JOIN dbo.v_R_User
ON dbo.v_R_System.User_Name0 = dbo.v_R_User.User_Name0
INNER JOIN dbo.v_GS_COMPUTER_SYSTEM
ON dbo.v_R_System.Name0 = dbo.v_GS_COMPUTER_SYSTEM.Name0
INNER JOIN v_GS_PC_BIOS
ON dbo.v_R_System.ResourceID = dbo.v_GS_PC_BIOS.ResourceID
WHERE
dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%'
OR dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%'
OR dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%'
返回这个:
╔══════════════╦════════════════════╦═════════╗
║ ComputerName ║ App ║ Version ║
╠══════════════╬════════════════════╬═════════╣
║ PC1 ║ MS Word ║ 12 ║
║ PC1 ║ Adobe Reader ║ 10.0.10 ║
║ PC1 ║ Adobe Flash Player ║ 15.1 ║
║ PC2 ║ MS Word ║ 15 ║
║ PC2 ║ Adobe Reader ║ 11.0.07 ║
║ PC2 ║ Adobe Flash Player ║ 16 ║
╚══════════════╩════════════════════╩═════════╝
我想return这种方式的信息:
╔══════════════╦═════════╦═════════╦══════════════╦═════════╦════════════════════╦═════════╗
║ ComputerName ║ App1 ║ App1Ver ║ App2 ║ App2Ver ║ App3 ║ App3Ver ║
╠══════════════╬═════════╬═════════╬══════════════╬═════════╬════════════════════╬═════════╣
║ PC1 ║ MS Word ║ 12 ║ Adobe Reader ║ 10.0.10 ║ Adobe Flash Player ║ 15.1 ║
║ PC2 ║ MS Word ║ 15 ║ Adobe Reader ║ 11.0.07 ║ Adobe Flash Player ║ 16 ║
╚══════════════╩═════════╩═════════╩══════════════╩═════════╩════════════════════╩═════════╝
此数据库存储在 SQL Server 2008 R2 上。
提前致谢。
你可以使用 case based aggregation
,这里的 like
还有一个问题,因为你使用的是 % 通配符,索引不会被使用,并且在大数据集上会变慢
最好使用组 ID 列并在应用程序名称和组之间建立映射 table,并在查询中使用组 ID。
SELECT
dbo.v_R_System.Name0 [ComputerName],
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%' then 'MS Word' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%MS Word%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App1Ver
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%' then 'Adobe Reader' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Adobe Reader%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App2Ver
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%' then 'Flash Player' end ) as App1,
max(case when dbo.v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 LIKE '%Flash Player%' then dbo.v_GS_ADD_REMOVE_PROGRAMS.Version0 end ) as App3Ver
FROM
dbo.v_R_System
INNER JOIN dbo.v_GS_ADD_REMOVE_PROGRAMS
ON dbo.v_R_System.ResourceID = dbo.v_GS_ADD_REMOVE_PROGRAMS.ResourceID
INNER JOIN dbo.v_R_User
ON dbo.v_R_System.User_Name0 = dbo.v_R_User.User_Name0
INNER JOIN dbo.v_GS_COMPUTER_SYSTEM
ON dbo.v_R_System.Name0 = dbo.v_GS_COMPUTER_SYSTEM.Name0
INNER JOIN v_GS_PC_BIOS
ON dbo.v_R_System.ResourceID = dbo.v_GS_PC_BIOS.ResourceID
group by dbo.v_R_System.Name0