[英]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.