Reputation: 3
I have a table that I need to join with itself and find the missing items and I'm stuck. Maybe it's just an inexperience issue, but I seem to only be able to think in terms of a loop to accomplish what I want.
Essentially the table is as follows:
packageID Server
1 baseline
2 baseline
3 baseline
1 server1
3 server1
2 server2
3 server2
What I'm hoping to accomplish is to find what packages are missing from each server. I can get this on a server by server basis like so:
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
Which gives me what I want on an individual server basis.
packageID Server
2 server1
How would I accomplish getting a list of each package a particular server is missing from the baseline?
Upvotes: 0
Views: 95
Reputation: 1117
Try this scripts,
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
Upvotes: 0
Reputation: 5669
Assuming a view with the list of SERVERS, and take it as pseudo-SQL as I can't test it, something like this should work I think...
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;
Upvotes: 1