【问题标题】:How can I use calculated alias in Order by clause?如何在 Order by 子句中使用计算别名?
【发布时间】:2020-01-14 21:53:07
【问题描述】:

表格很简单:

ID   start_date    end_date
1    2015-10-01    2015-10-02
2    2015-10-02    2015-10-03
3    2015-10-05    2015-10-06
4    2015-10-07    2015-10-08

ID 1 和 2 属于一个项目,因为 end_date 等于 start_date,ID 3 和 4 是不同的。

这是查找相同项目并按其花费时间排序的查询:

select P1.Start_Date, (
    select min(P.End_Date)
    from Projects  as P
    where P.End_Date not in (select Start_Date from Projects )
        and P.End_Date > P1.Start_Date
) as ED
from Projects as P1
where P1.Start_Date not in (select End_Date from Projects )
order by datediff(day, P1.Start_Date, ED)

问题是:order by子句中的ED无效,但是不带datediff使用时有效:

order by ED

datediff 是在 select 子句之后计算的吗?有谁能解释一下吗?谢谢。

【问题讨论】:

    标签: sql-server tsql sql-order-by datediff


    【解决方案1】:

    您可以简单地使用CROSS APPLY 来计算此列,如下所示:

    DECLARE @Projects TABLE
    (
        [ID] SMALLINT
       ,[start_date] DATETIME
       ,[end_date] DATETIME
    );
    
    INSERT INTO @Projects ([ID], [start_date], [end_date])
    VALUES ('1', '2015-10-01', '2015-10-02')
          ,('2', '2015-10-02', '2015-10-03')
          ,('3', '2015-10-05', '2015-10-06')
          ,('4', '2015-10-07', '2015-10-08');
    
    select P1.Start_Date, ED
    from @Projects as P1
    CROSS APPLY
    (
        select min(P.End_Date)
        from @Projects  as P
        where P.End_Date not in (select Start_Date from @Projects )
            and P.End_Date > P1.Start_Date
    ) DS(ED)
    where P1.Start_Date not in (select End_Date from @Projects )
    order by datediff(day, P1.Start_Date, ED);
    

    管理工作室的引擎似乎无法将别名ED 转换为有效的东西。例如,如果您将ED 替换为子查询,它将起作用。此外,以下是一种不好的做法将起作用:

    select P1.Start_Date, (
        select min(P.End_Date)
        from @Projects  as P
        where P.End_Date not in (select Start_Date from @Projects )
            and P.End_Date > P1.Start_Date
    ) as ED
    from @Projects as P1
    where P1.Start_Date not in (select End_Date from @Projects )
    order by datediff(day, P1.Start_Date, 2)
    

    而不是alias,我们使用要排序的列号。所以,你的代码没有问题。

    【讨论】:

    • 谢谢,它有效。但是我仍然很困惑为什么在我的代码中按 ED 排序有效,但按 datediff(day, P1.Start_Date, ED) 排序却说 ED 列名无效。有什么想法吗?
    • @IanJay 检查编辑。我想这是 SSMS 的一些限制 - 您的代码是有效的。
    • 非常感谢。你是对的,使用索引而不是别名工作,有点奇怪。我猜在 order by 子句中使用 DateDiff(..., ..., ED) 时,引擎会在 Select 之后计算 DateDiff。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 2014-02-21
    • 1970-01-01
    • 2020-11-14
    • 2017-11-02
    相关资源
    最近更新 更多