避免在SQL中使用for循环

时间:2013-03-15 11:09:08

标签: sql

我有一张桌子,我需要自己加入并找到丢失的物品而且我被卡住了。也许这只是一个缺乏经验的问题,但我似乎只能用循环来思考我想要的东西。

基本上表格如下:

    packageID     Server
      1           baseline
      2           baseline
      3           baseline
      1           server1
      3           server1
      2           server2
      3           server2

我希望完成的是找到每台服务器中缺少的软件包。我可以按照服务器的基础在服务器上得到这个:

    SELECT base.*, ISNULL(dp.server,'server1') as Server
    FROM (SELECT DISTINCT packageID FROM DB1
          WHERE server = 'baseline') base
    LEFT OUTER JOIN 
         (SELECT packageID, server FROM DB1
          WHERE server = 'server1') dp
   WHERE dp.server IS NULL

在个人服务器的基础上,这给了我想要的东西。

    packageID     Server
       2          server1 

如何从基线中获取特定服务器缺少的每个包的列表?

2 个答案:

答案 0 :(得分:1)

假设一个带有SERVERS列表的视图,并将其作为伪SQL,因为我无法测试它,我认为这样的事情应该起作用......

SELECT base.packageID, servers.server, 
             (SELECT count(*) 
                FROM base AS b1
               WHERE b1.packageId = base.packageId
                 AND b1.server    = servers.server) deployed
  FROM base, servers
 WHERE base.server = 'baseline'
   AND deployed = 0;

答案 1 :(得分:0)

试试这个脚本,

      DECLARE @DB1 TABLE
(
    PackageID INT
    ,Server VARCHAR(50)
)


INSERT INTO @DB1 VALUES(1,'baseline')
INSERT INTO @DB1 VALUES(2,'baseline')
INSERT INTO @DB1 VALUES(3,'baseline')
INSERT INTO @DB1 VALUES(1,'server1')
INSERT INTO @DB1 VALUES(3,'server1')
INSERT INTO @DB1 VALUES(2,'server2')
INSERT INTO @DB1 VALUES(3,'server2')

;WITH CTE_Package AS
(
    SELECT DISTINCT PackageID 
        , ROW_NUMBER() OVER(order by PackageID) AS ID
    FROM @DB1
)
,CTE_Servers AS
(
    SELECT DISTINCT Server 
        , ROW_NUMBER() OVER(order by PackageID) AS ID
    FROM @DB1
)
,CTE_Server_Packages AS
(
    SELECT DISTINCT P.PackageId, S.Server   
    FROM CTE_Servers S
    CROSS JOIN CTE_Package P    
)
SELECT Server, PackageID
FROM 
(
    SELECT SP.Server, SP.PackageID , D.PackageID [ActualPackage], D.Server [ActualServer]
    FROM CTE_Server_Packages SP
    LEFT JOIN @DB1 D
            ON D.PackageID = SP.PackageID
            AND D.Server = SP.Server
) AS TEMP
WHERE TEMP.ActualServer IS NULL
相关问题