ORDER BY不使用别名

时间:2017-09-25 12:17:21

标签: sql sql-server case sql-server-2014 alias

Hello Stack Overflow社区!

我和我的同事一起坐在这里,我们正试图解决我们目前在MSSQL 2014上遇到的问题。

我们有一个包含多个列的表,其中两列包含Date。 只是为了理解;一个日期(' Liefertermin')显示何时/是否实际交付,另一个(' FreiesDatum1')显示何时计划交付。

如果' Liefertermin'不是空的然后它应该出现,否则' FreiesDatum1'应该出现。 我们使用以下查询解决了这个问题:

SELECT
    CASE
       WHEN Liefertermin is null THEN cast(FreiesDatum1 as date)
       ELSE Liefertermin
    END as SortDate
FROM Beleg

SELECT-query中当然还有其他一些列,但这些列对于问题来说并不是必需的。我们希望将排序动态化,因此我们可以在不同类型之间进行选择。为此,我们在开头声明了一个变量(@Sort),并在'命令之后设置了一个CASE-Statement。

现在我们面临的问题是:

如果它位于CASE语句中,我们无法通过上面选择的' SortDate'进行排序。如果我们只是做order by 'SortDate',它就会毫无问题地工作。

这是我们的尝试,但不起作用:

order by CASE
            when @Sort=1 then 'SortDate'
            when @Sort=2 then 'Liefertermin'
            when @Sort=3 then 'Name'
          END

@ Sort = 1不,但@ Sort = 2和@ Sort = 3确实有效,所以我猜CASE本身没有问题。删除标记后,我收到一个错误,即列' SortDate'不存在。

我们已经尝试将别名更改为[SortDate]或' SortDate'没有任何成功,也尝试使用派生表,但我们得到了相同的结果。

我们在这里搜索了这些论坛并尝试了解决CASE语句其他问题的所有解决方案,但这些都没有奏效。

真的希望在这里得到帮助! 问候 3m7ecc

编辑:

这是完整的SQL-Query

Declare @Sort integer;
Set @Sort = 1

select
    Beleg.Belegnummer,
    Beleg.Belegtyp,
    Beleg.Datum,
    wp.Projekt,
    wp.Bezeichnung as 'Projektbezeichnung',
    BELEG.Adressnummer,
    BELEG.Firma,
    BELEG.Ort,
    convert(varchar(10),BELEG.Liefertermin,104) as Liefertermin,
    convert(varchar(10),BELEG.FreiesDatum1,104) as iLiefertermin,
    Beleg.Netto,
    BELEG.Status,
    cast(BELEG.Datum as date) as Erfassungsdatum,
    CASE
        when BELEG.Liefertermin is null then Beleg.FreiesDatum1
        else BELEG.Liefertermin
    END as SortDate
from BELEG
left join WPROJEKT as WP on (wp.Id = BELEG.Projekt)
    where 
    (('01.09.2017' is null or convert(varchar(10),BELEG.Liefertermin,104) >= '01.09.2017')
        and ('31.10.2017' is null or convert(varchar(10),BELEG.Liefertermin,104) <= '31.10.2017')) 
    and Beleg.belegtyp = 'B'
    and ((BELEG.Liefertermin is null
    and BELEG.FreiesDatum1 is null)
    or (BELEG.Liefertermin <= GETDATE() or BELEG.FreiesDatum1 <= GETDATE()))

ORDER BY
CASE WHEN @Sort = 1 then SortDate END DESC,
CASE WHEN @Sort = 2 then Liefertermin END DESC,
CASE WHEN @Sort = 3 then BELEG.Belegnummer END DESC

5 个答案:

答案 0 :(得分:1)

<强>已更新

您需要将当前的select语句包装在父SELECT * FROM中,然后在结尾添加order by语句,如下所示:

SELECT * FROM (
    SELECT
        Beleg.Belegnummer,
        Beleg.Belegtyp,
        Beleg.Datum,
        wp.Projekt,
        wp.Bezeichnung as 'Projektbezeichnung',
        BELEG.Adressnummer,
        BELEG.Firma,
        BELEG.Ort,
        convert(varchar(10),BELEG.Liefertermin,104) as Liefertermin,
        convert(varchar(10),BELEG.FreiesDatum1,104) as iLiefertermin,
        Beleg.Netto,
        BELEG.Status,
        cast(BELEG.Datum as date) as Erfassungsdatum,
        CASE
            when BELEG.Liefertermin is null then Beleg.FreiesDatum1
            else BELEG.Liefertermin
        END as SortDate
    FROM BELEG
    LEFT JOIN WPROJEKT as WP on (wp.Id = BELEG.Projekt)
        where 
        (('01.09.2017' is null or convert(varchar(10),BELEG.Liefertermin,104) >= '01.09.2017')
            and ('31.10.2017' is null or convert(varchar(10),BELEG.Liefertermin,104) <= '31.10.2017')) 
        and Beleg.belegtyp = 'B'
        and ((BELEG.Liefertermin is null
        and BELEG.FreiesDatum1 is null)
        or (BELEG.Liefertermin <= GETDATE() or BELEG.FreiesDatum1 <= GETDATE()))
) AS NewBeleg

ORDER BY
    CASE WHEN @Sort = 1 then NewBeleg.SortDate END DESC
    CASE WHEN @Sort = 2 then NewBeleg.Liefertermin END DESC
    CASE WHEN @Sort = 3 then NewBeleg.Name END DESC

答案 1 :(得分:1)

您不能在ORDER BY子句中使用别名列,因为逻辑上它在SELECT子句之前发生。您可以使用列号,例如ORDER BY 9会根据你的'Liefertermin'专栏对输出进行排序,但这被认为是一种不好的做法。最好的方法是将所有内容放在子查询中,例如:

SELECT * FROM
(SELECT... -- your whole select here without the ORDER BY clause
 ) as t1
ORDER BY
    CASE WHEN @Sort = 1 then SortDate END DESC
    CASE WHEN @Sort = 2 then Liefertermin END DESC
    CASE WHEN @Sort = 3 then Name END DESC

答案 2 :(得分:0)

您可以按顺序提供列号而不是列名 像

order by
CASE WHEN @Sort = 1 then 2 END DESC

其中2是Sortdate的列号。

否则,请不要使用别名来代替[tablename]。[columname]。

或您可以使用

select * from (

your query
...
) as T1

order by 
case WHEN @Sort = 1 then T1.[Sortdate] END DESC,

...

答案 3 :(得分:0)

您可以使用CTE并避免声明变量,更干净的方法!

{{1}}

CTE Reference

答案 4 :(得分:0)

由于我无法理解的原因,您似乎无法在使用ORDER BY的{​​{1}}中使用列别名。 您必须重新输入原始案例陈述,然后在ORDER BY CASE中重新输入,例如

CASE

因为@Sort只能等于一个值,尽管你只需要1个案例,例如

    ORDER BY
    CASE WHEN @Sort = 1 then (CASE
                                when BELEG.Liefertermin is null then Beleg.FreiesDatum1
                                else BELEG.Liefertermin
                              END) END DESC
    CASE WHEN @Sort = 2 then NewBeleg.Liefertermin END DESC
    CASE WHEN @Sort = 3 then NewBeleg.Name END DESC