将左连接重写为索引视图的 where 子句

Posted

技术标签:

【中文标题】将左连接重写为索引视图的 where 子句【英文标题】:Rewriting left join as a where clause for indexed view 【发布时间】:2018-08-14 15:49:15 【问题描述】:
SELECT *
FROM [dbo].[CountData] CD
INNER JOIN [dbo].[Count] C ON CD.CountId = C.CountId
LEFT JOIN [dbo].[Leg] L ON C.IntersectionId = L.IntersectionId AND CD.ApproachId = L.ApproachId 
WHERE L.IntersectionId IS NULL 

我怎样才能重写这个查询使得不涉及 LEFT JOIN。最终目标是获得一个可以作为索引视图接受的查询:https://www.brentozar.com/archive/2013/11/what-you-can-and-cant-do-with-indexed-views/(不允许左连接)

注意:不允许子查询

【问题讨论】:

为什么要索引视图? 因为我想编写一个复杂的约束spaghettidba.com/2011/08/03/…,它使用不存在的值来强制违反唯一性 某事告诉我你解决这个问题的方法不对。 仅供参考,您可以制作一个可用作约束的函数。您使用的是什么版本的 SQL Server? @CuriousDeveloper 我没有看到约束中编写良好的函数存在问题。也许您可以详细说明为什么某个函数在您的问题中不起作用。 【参考方案1】:

你可以使用NOT EXISTS重写它:

SELECT *
FROM [dbo].[CountData] CD
JOIN [dbo].[Count] C
  ON CD.CountId = C.CountId
WHERE NOT EXISTS (SELECT 1 FROM [dbo].[Leg] L
                  WHERE C.IntersectionId = L.IntersectionId 
                    AND CD.ApproachId = L.ApproachId)

【讨论】:

索引视图中不允许子查询,将更新问题

以上是关于将左连接重写为索引视图的 where 子句的主要内容,如果未能解决你的问题,请参考以下文章

带有两个不同 where 子句的内/左连接

与 where 子句不工作的左连接

在 WHERE 子句中使用连接列时,Mysql 未在 LEFT JOIN 中使用索引

左连接的where子句中的Mysql查询错误

mysql 查询 - 使用左连接和 where 子句的多个计数

如何将左连接横向 SQL 查询转换为 Laravel Eloquent 查询?