删除重复的子查询
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 开发人员非常强大的工具,尤其是用作递归查询时
我有一个复杂的 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 开发人员非常强大的工具,尤其是用作递归查询时