SQL - 根据列(相交)查找公共行

时间:2012-05-30 14:14:18

标签: sql-server sql-server-2008 tsql

鉴于下表:

InstalledApps

MachineName | AppName | Version
-------------------------------
machine01   | App01   | 1.1
machine01   | App02   | 1.0
machine01   | App03   | 1.5
machine02   | App04   | 2.0
machine02   | App02   | 1.0
machine02   | App01   | 1.1
machine03   | App06   | 7.9.9
machine03   | App01   | 1.1
machine03   | App07   | 11.5
machine03   | App02   | 1.0

我需要选择给定“n”台机器常见的Apps。它是“n”组之间的交叉。但是,我很难想出一个像样的查询。

我知道我可以这样做:

SELECT AppName, Version 
FROM InstalledApps 
WHERE MachineName = 'machine01'

INTERSECT

SELECT AppName, Version 
FROM InstalledApps 
WHERE MachineName = 'machine02' 

那会给我

AppName | Version
------------------
App01   | 1.1
App02   | 1.0

但是,有没有办法可以在不必事先知道机器数量的情况下做到这一点?像

这样的东西
SELECT...... 
FROM InstalledApps 
WHERE MachineName IN ('machine01',...'machine99')

4 个答案:

答案 0 :(得分:4)

我认为这应该适用于一般情况:

SELECT AppName, Version, COUNT(DISTINCT(MachineName)) AS MachineCount
FROM InstalledApps
GROUP BY
  AppName, Version
HAVING
  COUNT(DISTINCT(MachineName)) > 1

答案 1 :(得分:1)

您可以使用Row_Number功能和Partition数据与机器名称

Select AppName, [Version] From 
(
    Select Row_Number() Over(Partition By MachineName Order by AppName) RowId, * 
    From InstalledApps
)K
Where K.RowId = 2

答案 2 :(得分:0)

您可以参数化IN查询

Declare @value varchar(max)
Declare @sql varchar(max)
select @value = 'machine1,machine2,machine3'
SELECT @sql = 'SELECT * FROM InstalledApps  WHERE MachineName in (' + @value+ ')'

 exec sp_executeSQL @sql 

或者您甚至可以使用子查询来获取所有值

SELECT * FROM InstalledApps WHERE MachineName in (SELECT MachineName FROM InstalledApps    group by MachineName HAVING COUNT(DISTINCT(MachineName)) > 1)

答案 3 :(得分:0)

您可以通过分组执行此操作。假设InstalledApps表中的给定应用程序没有重复的计算机:

select apps
from InstalledApps
group by apps
having sum(case when machine in (<list of machines>) then 1 else 0 end) = <number of machines>

如果您的计算机上有重复的应用程序:

select apps
from (select distinct apps, machine from InstalledApps) ia
group by apps
having sum(case when machine in (<list of machines>) then 1 else 0 end) = <number of machines>

并且,我在想​​如果您不想计算机器数量,那么您可能需要使用动态SQL或将机器名称存储在临时表中。