[英]SQL Server Conditional Order By
我在 SQL Server 2005 中有一个 SQL 查询,当我包含条件订单时,该查询会中断。 当我删除订单时,查询有效。 当我明确地按条件编写顺序(例如,按 p.Description 顺序)时,它可以工作。 当我包含条件顺序时,我收到错误,
'Conversion failed when converting character string to smalldatetime data type'
SQL 服务器没有向我显示导致此错误的代码行。 我想知道如何解决这个问题,以便我可以使用条件顺序或排除转换中哪个列失败。
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!
根据上一个答案,尝试:
order by
case @SortBy
when 'product' then p.Description
when 'vendor' then v.LongName
else convert(VARCHAR(25),a.DateAdded,20)
这应该为您提供所需的排序,因为它将格式化日期字符串 yyyy-mm-dd hh:mm:ss。
您可以为每种数据类型使用一种情况:
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
在ORDER BY
中使用CASE
表达式时,返回的数据类型必须始终相同。
如果不使用动态 SQL 或某种形式的决策逻辑 (IE: IF
) 来突破不同的查询,您就无法挑选您想要的东西——INT、DATETIME、VARCHAR 等。
在此示例中,您可以使用 CAST/CONVERT 将 DATETIME 数据类型更改为适当的 VARCHAR。 但是,除非您知道问题发生的原因,否则您将来可能会再次这样做。
列列表中的 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
最后一个有点难看,如果可以的话更好;
CASE WHEN @SortBy = '' THEN cda.StartDate END
如果您关心性能,您可能需要一种不同的方法: 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.