删除重复的子查询

Remove duplicate sub-query

我有一个复杂的 SQL 查询,可以简化为以下内容:

Select ColA,ColB,ColC,ColD
From MyTable
Where (ColA In (Select ItemID From Items Where ItemName like '%xxx%') 
    or ColB In (Select ItemID From Items Where ItemName like '%xxx%'))

可以看到,子查询出现了两次。编译器是否足够智能以检测到这一点并仅获取一次子查询的结果?还是子查询运行两次?

仅供参考,table Items 大约有 20,000 行,MyTable 大约有 200,000 行。

有没有另一种方法可以重写这个SQL语句,使子查询appears/runs只出现一次?

更新:主查询中的 Where 子句是动态的,仅在需要时添加(即仅当用户搜索 'xxx' 时)。因此,无法更改主 select 语句或重新构建查询。

不保证会按照实际的执行顺序。这取决于您如何编写查询。相同的子查询通常只执行一次。 标准 SQL.

中有一个 WITH 子句
WITH mySubQuery AS
(
  [the subquery code]
)

SELECT * FROM
    mySubQuery AS sq
WHERE xyz IN (mySubQuery)

UPDATE 您要求不更改查询,只是 WHERE

可以直接在调用的地方打包CTE(未测试):

Select ColA,ColB,ColC,ColD
From MyTable
Where EXISTS (SELECT 1 FROM (Select i.ItemID 
                             From Items AS i 
                             Where iItemName like '%xxx%') AS itm 
              WHERE itm.ItemID=MyTable.ColA OR itm.ItemID=MyTable.ColB) 

上一个

我觉得这个应该是一样的...

WITH MyCTE AS
(
    Select ItemID From Items Where ItemName like '%xxx%'
)
Select ColA,ColB,ColC,ColD
From MyTable
Where EXISTS (SELECT 1 FROM MyCTE WHERE ItemID=ColA OR ItemID=ColB) 

子字符串 LIKE 搜索肯定不高效。

如果您可以使用 LIKE 过滤器将 "Items" 减少到几行,您必须测试哪个最快。

你也可以这样写查询:

SELECT ColA, ColB, ColC, ColD
FROM MyTable
WHERE EXISTS(
  (SELECT ItemID FROM Items WHERE ItemName LIKE '%xxx%') 
  INTERSECT
  SELECT t.v FROM (VALUES (ColA), (ColB)) AS t(v) )

SQL 程序员可以在这种情况下使用 CTE(通用 Table 表达式)

您可以使用子查询定义一次 CTE,并通过多次引用在 SQL 语句中使用它。

样本请参考SQL CTE Common Table Expression tutorial CTE 是 SQL 开发人员非常强大的工具,尤其是用作递归查询时