Using SQL Server 2012 (LocalDB), I have three tables:
BESEXT.COMPUTER
BESEXT.ANALYSIS_PROPERTY
BESEXT.ANALYSIS_PROPERTY_RESULT
These contains following info:
First, I perform the following query:
SELECT
AR.ComputerID,
AP.Name,
AR.Value
FROM BESEXT.ANALYSIS_PROPERTY_RESULT AR
JOIN BESEXT.ANALYSIS_PROPERTY AP ON AP.ID = AR.PropertyID
AND AP.ID IN (1672, 1673, 1674)
ORDER BY AR.ComputerID, AP.Name
Which yields the following result:
ComputerID Name Value
---------- ---- -----
595640 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
595640 SequenceName Windows 8.1 x64 - Mobile Device Image
595640 SequenceVersion 3.2
631459 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
631459 SequenceName Windows 8.1 x64 - Mobile Device Image
631459 SequenceVersion 3.2
In BESEXT.COMPUTER I have the following values:
ID ComputerID ComputerName
-- ---------- ------------
1 595640 PO121203866
2 631459 PO121201739
3 1101805 PO121201100
I want to perform a left outer join of all my computer objects on the first select, so that I know which computers I do not have a value for.
So, first I do a simple inner join on the previous selection:
SELECT
C.ComputerName,
R.ComputerID,
R.Name,
R.Value
FROM (
SELECT
AR.ComputerID,
AP.Name,
AR.Value
FROM BESEXT.ANALYSIS_PROPERTY_RESULT AR
JOIN BESEXT.ANALYSIS_PROPERTY AP ON AP.ID = AR.PropertyID
AND AP.ID IN (1672, 1673, 1674)
) R
JOIN BESEXT.COMPUTER C ON C.ComputerID = R.ComputerID
ORDER BY R.ComputerID, R.Name
Which, predictably, yields the following resultset:
ComputerName ComputerID Name Value
------------ ---------- ---- -----
PO121203866 595640 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121203866 595640 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121203866 595640 SequenceVersion 3.2
PO121201739 631459 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121201739 631459 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121201739 631459 SequenceVersion 3.2
Now, for the grand finale, let's do the LEFT OUTER JOIN:
SELECT
C.ComputerName,
R.ComputerID,
R.Name,
R.Value
FROM (
SELECT
AR.ComputerID,
AP.Name,
AR.Value
FROM BESEXT.ANALYSIS_PROPERTY_RESULT AR
JOIN BESEXT.ANALYSIS_PROPERTY AP ON AP.ID = AR.PropertyID
AND AP.ID IN (1672, 1673, 1674)
) R
-- LEFT OUTER JOIN ADDED HERE!
LEFT OUTER JOIN BESEXT.COMPUTER C ON C.ComputerID = R.ComputerID
ORDER BY R.ComputerID, R.Name
This yields the exact same resultset as with the inner join!
This is not what I'm looking for, and it is not at all what I was expecting. Now it's pretty late here and I'm basically doing some work out of insomnia, but I think this is about as simple and example of an Outer Join as it can get, right? The result I'm looking to achieve with the outer join is this:
ComputerName ComputerID Name Value
PO121203866 595640 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121203866 595640 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121203866 595640 SequenceVersion 3.2
PO121201739 631459 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121201739 631459 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121201739 631459 SequenceVersion 3.2
PO121201100 NULL NULL NULL
PO121201100 NULL NULL NULL
PO121201100 NULL NULL NULL
P.S.: To be completely honest, the result I'm looking for is more like this, but I feel that would be a different question altogether:
ComputerName Name Value
------------ ---- -----
PO121203866 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121203866 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121203866 SequenceVersion 3.2
PO121201739 DisplayName Windows 8.1 x64 - Mobile Device Image - v3.2
PO121201739 SequenceName Windows 8.1 x64 - Mobile Device Image
PO121201739 SequenceVersion 3.2
PO121201100 DisplayName NULL
PO121201100 SequenceName NULL
PO121201100 SequenceVersion NULL
The query you're looking can be written simply as this:
SELECT ComputerName, A.ComputerID, Name, Value FROM BESEXT.COMPUTER A
CROSS JOIN (SELECT * FROM BESEXT.ANALYSIS_PROPERTY WHERE ID BETWEEN 1672 AND 1674) B
LEFT JOIN BESEXT.ANALYSIS_PROPERTY_RESULT C ON A.ComputerId = C.ComputerId AND B.ID = C.PropertyId
ORDER BY ComputerId, Name
Start by getting all of the computer-property combinations you care about:
SELECT * FROM BESEXT.COMPUTER A
CROSS JOIN (SELECT * FROM BESEXT.ANALYSIS_PROPERTY WHERE ID BETWEEN 1672 AND 1674) B
This yields the results:
ID ComputerId ComputerName ID Name
-- ---------- ------------ -- ----
1 595640 PO121203866 1672 DisplayName
2 631459 PO121201739 1672 DisplayName
3 1101805 PO121201100 1672 DisplayName
1 595640 PO121203866 1673 SequenceName
2 631459 PO121201739 1673 SequenceName
3 1101805 PO121201100 1673 SequenceName
1 595640 PO121203866 1674 SequenceVersion
2 631459 PO121201739 1674 SequenceVersion
3 1101805 PO121201100 1674 SequenceVersion
From there, you simply perform a left join on BESEXT.ANALYSIS_PROPERTY_RESULT
to get your values, and you include the ORDER BY
clause to sort it.