2017-09-25 91 views
1

Hello Stack Overflow Community!ORDER BY不能與別名一起使用的MSSQL CASE

我坐在這裏,我的同事,我們正在努力解決我們目前有MSSQL 2014

的問題。我們有一個表列數,其中它們中的兩個包含日期。 只是爲了理解;一個日期('Liefertermin')顯示何時/是否實際交付,另一個日期('FreiesDatum1')顯示計劃何時交付。

如果'Liefertermin'不是空的,它應該顯示,否則'FreiesDatum1'應該出現。 我們用下面的查詢其作品,因爲它應該解決了這個:

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

當然也有在SELECT查詢一些列,但這些都不是必要的問題。我們希望分類具有動態性,所以我們可以選擇不同的類型。爲此,我們在開始時聲明瞭一個變量(@Sort),並在'order by'之後設置了一個CASE語句。

現在還出現了我們面臨的問題:

我們無法通過「SortDate」命令,也就是上面選擇,如果它矗立在CASE語句。如果我們只是做order by 'SortDate'它工作沒有任何問題。

這是我們的嘗試,不工作:

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

@排序= 1沒有,但@排序= 2,@排序= 3做工作,所以我想有沒有問題與CASE本身。刪除標記時,出現錯誤,列'SortDate'不存在。

我們已經嘗試將別名更改爲[SortDate]或'SortDate'而沒有任何成功,並嘗試使用派生表,但我們得到了相同的結果。

我們在這裏搜索了這些論壇,並嘗試瞭解CASE語句的其他問題的每個解決方案,但沒有一個能夠工作。

真的很希望在這裏得到幫助! 問候 3m7ecc

編輯:

以下是完整的SQL查詢

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 
+1

我不認爲'SortDate'的順序正常工作。我會建議你使用沒有單引號的白色列名,使用類似[SortDate]或[Liefertermin]; –

+0

在每種情況下,您都按常量進行排序:''SortDate''是一個字符串,而不是對'SortDate'列的引用。我想你想刪除''' –

+0

首先感謝您的快速幫助,但正如我所說的,當我刪除標記,我得到了錯誤,該列不存在! – 3m7ecc

回答

1

不能在訂單,因爲排序邏輯它在SELECT子句之前發生使用別名列BY子句。您可以使用列號,例如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 
+0

我已經嘗試了數字,但沒有解決,但子查詢似乎工作! 唯一奇怪的是,我之前嘗試過,但沒有奏效。 也許我之前嘗試過的時候會忘記一些東西。 非常感謝! – 3m7ecc

1

修訂

你需要用你當前的SELECT語句在父SELECT * FROM,然後在末尾添加如下命令:

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 
+0

感謝您的幫助,但這不起作用。 它引發錯誤,'SortDate'是一個無效的列名! 如果我在CASE中的SortDate上添加SortDate標記,它就不會執行任何操作。沒有錯誤,但它不排序。 – 3m7ecc

+0

你可以用你試過的順序發佈整個SQL語句嗎?在'SortDate'周圍添加標記時,它將按字符串'SortDate'進行排序,這就是爲什麼它可以與標記一起使用 –

+0

這應該起作用。你注意到有三種不同的'case'表達式。 –

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, 

....

0

你可以使用CTE,避免聲明變量,更清潔的方式!

with your_cte as (
    select isnull(Liefertermin, FreiesDatum1) as SortDate 
    from beleg 
) 

select * from your_cte order by SortDate 

CTE Reference

0

對於我還不能捉摸一個原因,你似乎沒有BA能夠在使用CASEORDER BY使用列別名也。 您必須重新輸入原始案例聲明並將其放入ORDER BY CASE中,例如

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 

由於@Sort只能等於一個值,但您只需要1個例如

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