[英]SQL Server Conditional Order By
I have a SQL query in SQL Server 2005 that is breaking when I include a conditional order by.我在 SQL Server 2005 中有一个 SQL 查询,当我包含条件订单时,该查询会中断。 When I remove the order by, the query works.
当我删除订单时,查询有效。 When I explicitly write the order by condition (eg order by p.Description) it works.
当我明确地按条件编写顺序(例如,按 p.Description 顺序)时,它可以工作。 When I include the conditional order by, I get the error,
当我包含条件顺序时,我收到错误,
'Conversion failed when converting character string to smalldatetime data type'
SQL Server isn't showing me which line of code caused this error. SQL 服务器没有向我显示导致此错误的代码行。 I'm wondering how I can fix this so I can use the conditional order by or troubleshoot which column is failing in the conversion.
我想知道如何解决这个问题,以便我可以使用条件顺序或排除转换中哪个列失败。
declare @SearchTerm nvarchar(255)
declare @SortBy nvarchar(255)
declare @Months int
declare @VendorID int
declare @ProductID int
set @SearchTerm = 'focus'
set @SortBy = 'product'
set @Months = 3
set @VendorID = null
set @ProductID = null
-- This makes it so the @Month will filter by n number of months ago.
declare @PreviousMonths datetime
if @Months is null
begin
set @PreviousMonths = 24
end
else
begin
set @PreviousMonths = DateAdd(month, -@Months, GetDate())
end
select
a.dsAlertID as AlertID,
a.ProductID,
v.VendorID,
p.Description as ProductName,
v.LongName as VendorName,
a.Introduction,
a.Writeup,
a.DateAdded
from
ev_ds_Alerts a
left outer join
tblProducts p on a.ProductID = p.ProductID
left outer join
tblVendors v on v.VendorID = p.VendorID
where
( @SearchTerm is null or ( a.Writeup like '% ' + @SearchTerm + '%' or a.Introduction like '% ' + @SearchTerm + '%') )
and (( @Months is null ) or ( @Months is not null and a.DateAdded >= @PreviousMonths))
and (( @VendorID is null ) or ( @VendorID is not null and v.VendorID = @VendorID ))
and (( @ProductID is null ) or ( @ProductID is not null and p.ProductID = @ProductID ))
order by
case @SortBy
when 'product' then p.Description
when 'vendor' then v.LongName
else a.DateAdded
end
-- order by p.Description or v.LongName works when explicitly writing them out!
Per the previous answer, try:根据上一个答案,尝试:
order by
case @SortBy
when 'product' then p.Description
when 'vendor' then v.LongName
else convert(VARCHAR(25),a.DateAdded,20)
This should give you the sort you want, as it will format the date string yyyy-mm-dd hh:mm:ss.这应该为您提供所需的排序,因为它将格式化日期字符串 yyyy-mm-dd hh:mm:ss。
You can use one case for each data type:您可以为每种数据类型使用一种情况:
order by
case @SortBy
when 'product' then p.Description
when 'vendor' then v.LongName
else ''
end,
case @SortBy
when 'added' then a.DateAdded
else '1980-01-01'
end
When using a CASE
expression in an ORDER BY
-- the data types returned must always be the same.在
ORDER BY
中使用CASE
表达式时,返回的数据类型必须始终相同。
You can't cherry pick what you want -- INT, DATETIME, VARCHAR, etc. -- without using dynamic SQL or some form of decision logic (IE: IF
) to breakout the different queries.如果不使用动态 SQL 或某种形式的决策逻辑 (IE:
IF
) 来突破不同的查询,您就无法挑选您想要的东西——INT、DATETIME、VARCHAR 等。
In this example you could use CAST/CONVERT to change the DATETIME data type to an appropriate VARCHAR.在此示例中,您可以使用 CAST/CONVERT 将 DATETIME 数据类型更改为适当的 VARCHAR。 But unless you know why the issue is happening, you're likely to do it again in the future.
但是,除非您知道问题发生的原因,否则您将来可能会再次这样做。
A NULL in a the list of columns to order by is ignored, so you can break them down by type;列列表中的 NULL 被忽略,因此您可以按类型分解它们;
ORDER BY
CASE
WHEN @SortBy = 'product' THEN p.Description
WHEN @SortBy = 'vendor' THEN v.LongName
END
,
CASE WHEN @SortBy NOT IN ('product', 'vendor') THEN cda.StartDate END
Bit ugly for the last else, better if you could;最后一个有点难看,如果可以的话更好;
CASE WHEN @SortBy = '' THEN cda.StartDate END
If you care about performance, you might want a different approach: 1. Wrap your select in an inline TVF 2. Use two different SELECTs, so that they can get two different plans, potentially more efficient that the generic one-size-fits-all one plan you are getting now:如果您关心性能,您可能需要一种不同的方法: 1. 将 select 包装在一个内联 TVF 中 2. 使用两个不同的 SELECT,以便他们可以获得两个不同的计划,可能比通用的单一尺寸更有效 -你现在得到的所有一个计划:
IF @SortBy='product' BEGIN
SELECT AlertID,
(snip)
FROM MyTvf
ORDER BY Description ;
RETURN @@ERROR ;
END
IF @SortBy='Vendor' BEGIN
SELECT AlertID,
(snip)
FROM MyTvf
ORDER BY LongName ;
RETURN @@ERROR ;
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.