【问题标题】:What is this join type: JOIN [Status] ON [Name] = 'Acknowledged'这是什么连接类型:JOIN [Status] ON [Name] = 'Acknowledged'
【发布时间】:2018-12-09 15:17:08
【问题描述】:

我在this 问题中遇到了以前从未见过的连接样式:

UPDATE SomeTable
SET CurrentStatusID = [Status].[ID]
FROM SomeTable
 RIGHT JOIN [Status] ON [Name] = 'Acknowledged'
WHERE SomeTable.[ID] = @SomeID

有人能解释一下吗?这似乎是典型连接的捷径。换句话说:

Select * from Items
JOIN ItemTypes on Code = 'TASK'

是一个快捷方式:

Select * from Items i
JOIN ItemTypes it on i.ItemTypeId = it.Id
where it.Code = 'TASK'

正确吗?还是我错过了什么?

【问题讨论】:

  • 不,这是一个带有 WHERE 子句的近乎 CROSS JOIN。 example.
  • 您是否尝试过运行这两个查询,假设您可以这样做?您可能会看到结果集并不相同。
  • 这是胡言乱语。写它的人不知道他们在做什么。将其更改为 CROSS JOIN 并将 ON 条件移动到 WHERE 子句中;它会做完全相同的事情,但阅读起来更有意义。
  • 是的,胡言乱语。右连接通常会为 SomeTable 列保留 Status 中的所有行,NULL,但 SomeTable.[ID] = @SomeID 意味着它无论如何都是内部连接。所以基本上它会找到来自[Status] 的所有行,其中[Name] = 'Acknowledged' 并从中选择一个任意ID 并使用它来更新CurrentStatusID。如果没有这样的行,则不会更新任何内容。
  • 知道了,好的,非常感谢,这样就解决了。

标签: sql sql-server


【解决方案1】:

不正确,这不是捷径,至少不是您认为的捷径(准确地说:像这样写的INNER JOIN 可以被认为是CROSS JOIN + WHERE 的捷径,但我建议您避免认为就是这样)。

在任何类型的JOIN 中,您实际上都可以使用常量,不仅是列,而且对于OUTER JOIN,结果会根据您编写的位置而有所不同。

考虑以下 2 个示例:

WITH TableA(ID) AS (
    SELECT 1
    UNION
    SELECT 2
), TableB(ID, Type) AS (
    SELECT 1, 'Type1'
    UNION
    SELECT 1, 'Type2'
    UNION
    SELECT 2, 'Type2'
)
SELECT *
FROM TableA
LEFT OUTER JOIN TableB ON TableA.ID = TableB.ID
WHERE Type= 'Type1'

WITH TableA(ID) AS (
    SELECT 1
    UNION
    SELECT 2
), TableB(ID, Type) AS (
    SELECT 1, 'Type1'
    UNION
    SELECT 1, 'Type2'
    UNION
    SELECT 2, 'Type2'
)
SELECT *
FROM TableA
LEFT OUTER JOIN TableB ON TableA.ID = TableB.ID AND Type= 'Type1'

第一个示例说:加入所有内容,但只返回包含 Type1 的记录。
第二个示例说:仅当您在右侧有 Type1 但返回所有内容时才加入,即使您未能加入 (LEFT OUTER JOIN)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-03
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    相关资源
    最近更新 更多