【问题标题】:Write a where clause that compares two columns to the same subquery?编写一个 where 子句,将两列与同一个子查询进行比较?
【发布时间】:2022-12-10 05:33:31
【问题描述】:

我想知道是否有可能使 where 子句将 2 列与同一子查询进行比较。我知道我可以制作一个临时表/变量表或将相同的子查询写两次。但我想尽可能避免所有这些。 Subquery 又长又复杂,如果我必须写两次,会造成很大的开销。

这是我正在尝试做的一个例子。

SELECT * FROM Table WHERE (Column1 OR Column2) IN (Select column from TABLE) 

我正在寻找一个简单的答案,这可能只是否,但如果没有任何太详细的内容可能的话,请告诉我。

我更新了选择以使用 OR 而不是 AND 因为这更好地澄清了我的问题。

【问题讨论】:

  • 为什么是子查询?为什么不是正确的join on othertable.col in (this table.col1, this table.col2)?哪怕你只子查询一次,它仍然可能被评估两次。那么,您的目标是对性能最不意外,还是最容易让人眼前一亮?
  • 也许您过于简单化了,但是仅从 Table1 中选择您只需要一个半连接,所以我建议存在在这里效果最好。
  • @AaronBertrand 现在我想到它可能真的有用。这给了我一些工作的想法。将子查询转换为表连接并比较两列。我认为根据社区的回答,我有多种选择可供选择。感谢您的帮助。我最初的问题被否决了,这让我很难过。不太确定为什么我猜没有人喜欢我的问题。

标签: sql sql-server


【解决方案1】:

您给出的示例可能会使用存在, 如:

select *
from t1
where exists (
  select 1 from t2 
  where t2.col = t1.col1 and t2.col = t1.col2
);

【讨论】:

  • 这假设 col1 和 col2 匹配相同的 t2.col 值。我不太相信这是这里需要的,否则 OP 会/可能会使用 WHERE Column1 = Column2 and Column2 IN (Select column from TABLE),从而使这个问题变得不必要。
  • 是的,Column1 和 Column2 有不同的 IDS,但这确实给了我一些尝试的想法。谢谢。
【解决方案2】:

为防止重复编写复杂的子查询,您可以使用CTE (Common Table Expression)

;WITH MyFirstCTE (x) AS
(
   SELECT [column] FROM [TABLE1]
   -- add all the very complicated stuff here
)
SELECT *
FROM   Table2
WHERE  Column1 IN (SELECT x FROM MyFirstCTE)
AND    Column2 IN (SELECT x FROM MyFirstCTE)

或者使用 EXISTS:

;WITH MyFirstCTE (x) AS
(
   SELECT [column] FROM [TABLE1]
   -- add all the very complicated stuff here
)
SELECT *
FROM   Table2
WHERE  EXISTS (SELECT 1 FROM MyFirstCTE WHERE x = Column1)
AND    EXISTS (SELECT 1 FROM MyFirstCTE WHERE x = Column2)
  • 我故意使用笨拙的名字,最好选择更好的。
  • 我以 ; 开始它,因为如果它不是较大脚本中的第一个命令,则需要 ; 将 CTE 与其之前的命令分开。

【讨论】:

  • CTE 不保证它只会被评估一次,它只是让你只类型它一次。
  • (我之所以提到这一点,是因为 OP 担心“大量开销”,但不清楚它们到底意味着什么开销。)
  • 我的回答以“防止两次编写复杂的子查询”开始,我没有对性能做出任何声明,只是希望 sqlserver 能够找出最佳策略。
  • 只是为其他读者添加更多说明。
  • 这是一个选项,但存在开销问题。不过我会调查一下。谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 2018-03-24
  • 2014-01-07
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多