我有以下代码:
SELECT [TransactionId]
, min([Timestamp]) as [Begin]
, max([Timestamp]) as [End]
,DATEDIFF(ss, min([Timestamp]), max([Timestamp])) as [TurnAroundTime]
我可以在[Begin]
中使用[End]
和DATEDIFF
名称吗?
答案 0 :(得分:3)
否,它们与伪同步执行的语句不在同一语句中,因此在评估您的 DATEDIFF 函数时,Begin和End仍然不存在。
出于可读性考虑,无论如何,您都可以使用子查询-甚至更好地使用Common Table Expression-
WITH #computed AS (
SELECT
MIN(Timestamp) AS [Begin],
MAX(Timestamp) AS [End]
FROM YourTable
)
SELECT
[Begin],
[End],
DATEDIFF(ss, [Begin], [End]) TurnAroundTime
FROM #computed
在我的系统(SQL Server 2017)上,两种解决方案均导致完全相同的执行计划,因此CTE解决方案不会发生任何开销-不过请在您的系统上进行测试并进行检查。
旁注:尝试避免在列别名中使用保留字(例如Begin和End),以提高可读性并避免错误。
答案 1 :(得分:2)
不,你不能。
在任何单个SELECT
子句中,所有表达式都是“好像”被并行计算的。特别是,这意味着您不能拥有依赖于该单个子句中任何其他表达式的结果的表达式-该表达式的值尚不可用。
当然,大多数产品实际上会按某些(未指定的)顺序评估表达式,但是SQL Server会执行阻止您尝试引用其他表达式的语言规则。
请记住,在SQL中,您告诉系统您想要什么,而不是如何做到。像样的优化程序应该发现多个表达式使用MIN(Timestamp)
,并且观察到这是确定性函数,因此只需 evaluate 一次。