复杂的加入忽略'何处存在'

时间:2014-04-11 12:48:24

标签: sql-server tsql join exists

我需要检查主USICOAL数据库中的任何促销,但不要检查快照中的促销(简单):

SELECT U.[PROMOTION_NO]
      ,U.[STORE_NO]
      ,U.[PROMOTION_NAME]
      ,U.[SCHED_BGN_DATETIME] AS 'USICOAL START_DATE'
      ,U.[SCHED_END_DATETIME] AS 'USICOAL END_DATE'
      ,S.[SCHED_BGN_DATETIME] AS 'SNAPSHOT START_DATE'
      ,S.[SCHED_END_DATETIME] AS 'SNAPSHOT END_DATE'
FROM [REWARDS_SNAPSHOT_2471].[dbo].[PROMOTION] AS S
FULL OUTER JOIN [USICOAL].[dbo].[PROMOTION] AS U
ON S.PROMOTION_NO = U.PROMOTION_NO

但是USICOAL数据库没有显示正确的STORE_NO(即' 8882')而是会有一个在单独的表格上链接的随机数({{1所以我有以下查询:

STORE_GROUP_STORE

以上两项都是单独的,但最重要的是包括不在下面的查询中的商店(' 8882')所以我尝试将它们全部链接在一起,查询似乎忽略了第二部分:

SELECT UP.STORE_NO
       ,UP.PROMOTION_NO
FROM [USICOAL].[dbo].[PROMOTION] AS UP
LEFT JOIN [USICOAL].[dbo].[STORE_GROUP_STORE] AS US
ON UP.STORE_NO = US.STORE_GROUP_ID
WHERE US.STORE_NO = '8882'

我知道上面的内容很复杂,但由于数据库结构,我无法想到如何简化它。

2 个答案:

答案 0 :(得分:0)

我认为这是增加额外结果的一点

AND S.PROMOTION_NO IS NULL
OR U.SCHED_BGN_DATETIME != S.SCHED_BGN_DATETIME
OR U.SCHED_END_DATETIME != S.SCHED_END_DATETIME

您可能希望这取决于您的逻辑

    AND (S.PROMOTION_NO IS NULL
OR U.SCHED_BGN_DATETIME != S.SCHED_BGN_DATETIME
OR U.SCHED_END_DATETIME != S.SCHED_END_DATETIME)

答案 1 :(得分:0)

你的外部联接已经回到了前面。要在U中查找但不在S中的行,请从左侧连接S:

中选择
SELECT U.[PROMOTION_NO]
      ,U.[STORE_NO]
      ,U.[PROMOTION_NAME]
      ,U.[SCHED_BGN_DATETIME] AS 'USICOAL START_DATE'
      ,U.[SCHED_END_DATETIME] AS 'USICOAL END_DATE'
      ,S.[SCHED_BGN_DATETIME] AS 'SNAPSHOT START_DATE'
      ,S.[SCHED_END_DATETIME] AS 'SNAPSHOT END_DATE'
FROM [USICOAL].[dbo].[PROMOTION] AS U
LEFT JOIN [REWARDS_SNAPSHOT_2471].[dbo].[PROMOTION] AS S
  ON S.PROMOTION_NO = U.PROMOTION_NO
WHERE S.PROMOTION_NO IS NULL

这可能看似违反直觉;如何S.PROMOTION_NO等于主表中的键为空?

答案是在进行连接时评估连接条件。但在进行连接后评估where子句,当左连接未命中时,连接表中的所有列都为空。因此,要查找所有错过的连接,请通过仅保留连接表中具有空值的连接结果来过滤连接结果。