【发布时间】:2021-06-14 23:36:43
【问题描述】:
以下是我遇到的问题的简化示例。假设我有一个查询“SomeQuery”(SELECT...FROM...WHERE...),它的输出如下所示:
| Status | MyDate |
|---|---|
| A | 6/14/2021 |
| A | 6/12/2021 |
| B | 6/10/2021 |
| A | 6/8/2021 |
| B | 6/6/2021 |
| A | 6/4/2021 |
我需要获取最早的状态 A 日期,该日期大于状态 B 的最大日期。在这种情况下,2021 年 6 月 12 日。
我的查询如下所示:
SELECT
MIN(MyDate) AS DateNeeded
FROM
SomeQuery
WHERE
Status = 'A'
AND MyDate > (
SELECT
MAX(MyDate) AS MaxDateB
FROM
SomeQuery
WHERE
Status = 'B'
)
这可行,但我想避免运行子查询两次。我尝试为子查询的第一个实例分配一个别名,然后使用该别名代替第二个实例,但这会导致“无效对象名称”错误。
任何帮助将不胜感激。谢谢。
【问题讨论】:
-
如果没有实际的minimal reproducible example,很难提供答案,但很可能您可以使用窗口函数。
-
我会使用 CTE。您也许可以在日期和不同类型上将表加入回自身。
-
@drHodge 自联接可能很慢,实际上与子查询相同。窗口函数几乎可以肯定是最好的答案
-
也许您可以编辑您的问题并提供所需的结果
-
考虑到您实际上正在查看 2 个读数(一个 Status = A,一个 Status = B),那么几乎任何计划都需要阅读两次(甚至是 CTE)。一个窗口函数可能只执行一组读取,但会增加计算时间。另一种方法是首先将
SomeQuery的结果存储在#temporary 表中,并在Status, MyDate上使用非聚集索引,以便以一种有帮助的方式对其进行排序。使用索引,读取次数将最少并且几乎是瞬时的;但是您需要花费额外的时间来创建临时表。
标签: sql sql-server tsql subquery