【问题标题】:Why is a CTE needed to execute the following为什么需要 CTE 来执行以下操作
【发布时间】:2022-01-03 03:01:41
【问题描述】:

以下查询错误,列名“rowid”无效

  SELECT row_number() over (partition by sales_rep order by timestamp desc) as rowid, *
  FROM dbo.you_gettheidea
where rowid = 1

但是,以下版本可以完美运行。我不知道为什么。

with t1 as (SELECT row_number() over (partition by sales_rep order by timestamp desc) as rowid, *
FROM dbo.you_gettheidea)

Select * from t1
Where rowid = 1

SQL Server 12.0.2000

编辑:看来这个问题符合following answered question

【问题讨论】:

  • 查看 SQL 执行顺序where 子句对派生列 rowid 不可见
  • 如果我正确地关注this,SELECT 是第 6,而 WHERE 是第 4。因此,您对可见性的评论是有道理的。谢谢
  • 如果你正确地点击了那个链接,WHERE 是第 2 名,SELECT 是第 6 名,所以WHERE 看不到后续操作的任何结果

标签: sql sql-server partition-by


【解决方案1】:

您不能在同一语句的 where 子句中使用列别名。它不遵守执行顺序,这就是需要 CTE 的原因。请查看Execution order

  1. FROM 和 JOIN s。首先执行 FROM 子句和随后的 JOIN 以确定正在执行的数据的总工作集 查询。
  2. 在哪里。
  3. 分组依据。
  4. 有。
  5. 选择。
  6. 不同。
  7. 订购。
  8. 限制/偏移/顶部

【讨论】:

  • 是的,这就是答案。
  • 只是一个注释,JOIN 是 FROM 子句的一部分。
  • 是的!绝对是。谢谢。我刚刚提到了来自链接地址的订单以提高可读性。
【解决方案2】:

迟到的答案,但还有另一个选项没有 CTE 或子查询...WITH TIES

Select top 1 with ties *
 From  dbo.you_gettheidea
 Order By row_number() over (partition by sales_rep order by timestamp desc)

【讨论】:

  • 我无法让with ties 为我的目的工作。我正在运行的 SQL 版本一直试图将其解释为 CTE。
  • @ZdWhite 没有更多上下文,很难想象您的问题。只是为了好玩,这是一个工作示例dbfiddle.uk/…
  • 嗯,在重试此方法后,我确实让它工作了。结果似乎有点不正常,不知道为什么,但这似乎无关紧要。我喜欢这个替代方案,因为它比子查询甚至我喜欢的 CTE 更干净。谢谢!
  • @ZdWhite 全面披露:cte 方法......其中 RN=1 的性能更佳
  • @ZdWhite 我确实喜欢这种方法,因为没有额外的列,即 RN。也就是说,如果我的表有数百万行,我将使用 CTE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 2010-11-28
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 2013-04-29
相关资源
最近更新 更多