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
答案 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)
答案 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