左外部加入 SQL Server 2012 LocalDB 不工作?
Left outer join in SQL Server 2012 LocalDB not working?
使用 SQL Server 2012 (LocalDB),我有三个表:
BESEXT.COMPUTER
BESEXT.ANALYSIS_PROPERTY
BESEXT.ANALYSIS_PROPERTY_RESULT
这些包含以下信息:
- BESEXT.COMPUTER: ComputerIDs 和 ComputerNames 之间的映射
- BESEXT.ANALYSIS_PROPERTY: 可以映射到计算机的属性列表
- BESEXT.ANALYSIS_PROPERTY_RESULT:计算机的属性值列表
首先,我执行以下查询:
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
产生以下结果:
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
在 BESEXT.COMPUTER 中,我有以下值:
ID ComputerID ComputerName
-- ---------- ------------
1 595640 PO121203866
2 631459 PO121201739
3 1101805 PO121201100
我想在第一个 select 上执行所有计算机对象的左外连接,以便我知道哪些计算机没有值。
所以,首先我对前一个 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
这可以预见地产生以下结果集:
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
现在,作为压轴戏,让我们进行 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
这会产生 与内部联接完全相同的结果集!
这不是我想要的,也不是我所期待的。现在已经很晚了,我基本上是在做一些摆脱失眠的工作,但我认为这是 Outer Join 的最简单示例,对吧?我希望通过外部连接实现的结果是:
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.: 老实说,我正在寻找的结果更像是这样,但我觉得那将是一个完全不同的问题:
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
您正在寻找的查询可以简单地写成这样:
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
首先获取您关心的所有计算机-属性 组合:
SELECT * FROM BESEXT.COMPUTER A
CROSS JOIN (SELECT * FROM BESEXT.ANALYSIS_PROPERTY WHERE ID BETWEEN 1672 AND 1674) B
这会产生结果:
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
从那里,您只需在 BESEXT.ANALYSIS_PROPERTY_RESULT
上执行左连接来获取您的值,然后包含 ORDER BY
子句对其进行排序。
您可以通过使用交叉连接为所有计算机设置属性,然后使用左连接连接到已设置值的计算机的实际 属性 值来执行此操作:
SELECT * FROM (
SELECT
C.ComputerName,
C.ComputerID,
AP.Name,
AP.ID
FROM BESEXT.COMPUTER C
CROSS JOIN BESEXT.ANALYSIS_PROPERTY AP
WHERE AP.ID IN (1672, 1673, 1674)
) AP
LEFT JOIN BESEXT.ANALYSIS_PROPERTY_RESULT AR
ON AP.ComputerID = AR.ComputerID AND AP.ID = AR.PropertyID
ORDER BY AP.ComputerName DESC, AP.Name
作为一个L.O.J会是这样吗?
SELECT
R.ComputerName,
C.ComputerID,
C.Name,
C.Value
FROM BESEXT.COMPUTER R
-- LEFT OUTER JOIN ADDED HERE!
LEFT OUTER JOIN
(
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)
) C
ON C.ComputerID = R.ComputerID
ORDER BY C.ComputerID, C.Name
使用 SQL Server 2012 (LocalDB),我有三个表:
BESEXT.COMPUTER
BESEXT.ANALYSIS_PROPERTY
BESEXT.ANALYSIS_PROPERTY_RESULT
这些包含以下信息:
- BESEXT.COMPUTER: ComputerIDs 和 ComputerNames 之间的映射
- BESEXT.ANALYSIS_PROPERTY: 可以映射到计算机的属性列表
- BESEXT.ANALYSIS_PROPERTY_RESULT:计算机的属性值列表
首先,我执行以下查询:
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
产生以下结果:
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
在 BESEXT.COMPUTER 中,我有以下值:
ID ComputerID ComputerName
-- ---------- ------------
1 595640 PO121203866
2 631459 PO121201739
3 1101805 PO121201100
我想在第一个 select 上执行所有计算机对象的左外连接,以便我知道哪些计算机没有值。
所以,首先我对前一个 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
这可以预见地产生以下结果集:
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
现在,作为压轴戏,让我们进行 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
这会产生 与内部联接完全相同的结果集!
这不是我想要的,也不是我所期待的。现在已经很晚了,我基本上是在做一些摆脱失眠的工作,但我认为这是 Outer Join 的最简单示例,对吧?我希望通过外部连接实现的结果是:
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.: 老实说,我正在寻找的结果更像是这样,但我觉得那将是一个完全不同的问题:
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
您正在寻找的查询可以简单地写成这样:
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
首先获取您关心的所有计算机-属性 组合:
SELECT * FROM BESEXT.COMPUTER A
CROSS JOIN (SELECT * FROM BESEXT.ANALYSIS_PROPERTY WHERE ID BETWEEN 1672 AND 1674) B
这会产生结果:
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
从那里,您只需在 BESEXT.ANALYSIS_PROPERTY_RESULT
上执行左连接来获取您的值,然后包含 ORDER BY
子句对其进行排序。
您可以通过使用交叉连接为所有计算机设置属性,然后使用左连接连接到已设置值的计算机的实际 属性 值来执行此操作:
SELECT * FROM (
SELECT
C.ComputerName,
C.ComputerID,
AP.Name,
AP.ID
FROM BESEXT.COMPUTER C
CROSS JOIN BESEXT.ANALYSIS_PROPERTY AP
WHERE AP.ID IN (1672, 1673, 1674)
) AP
LEFT JOIN BESEXT.ANALYSIS_PROPERTY_RESULT AR
ON AP.ComputerID = AR.ComputerID AND AP.ID = AR.PropertyID
ORDER BY AP.ComputerName DESC, AP.Name
作为一个L.O.J会是这样吗?
SELECT
R.ComputerName,
C.ComputerID,
C.Name,
C.Value
FROM BESEXT.COMPUTER R
-- LEFT OUTER JOIN ADDED HERE!
LEFT OUTER JOIN
(
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)
) C
ON C.ComputerID = R.ComputerID
ORDER BY C.ComputerID, C.Name