具有混合数据类型的SQL Server动态ORDER BY:这是一个好主意吗?

Sco*_*ttE 3 t-sql sql-server-2005

我有存储过程,返回动态排序的结果.父文件夹(这是用于内容管理)具有RankTypeID字段,允许按Rank(0)排序,开始日期按升序排序(1),开始日期按降序排列(2),文档标题(3)

Rank是一个整数,date是smalldatetime,title是nvarchar.

...

ORDER BY
    Case Parent.RankTypeID
      When 0 Then dbo.Folders.Rank
      When 1 Then Cast(dbo.Documents.SortableDateStart As bigint)
      When 2 Then (1 - Cast(dbo.Documents.SortableDateStart As bigint))
      When 3 Then Cast(dbo.Documents.Title as sql_variant)
    End
Run Code Online (Sandbox Code Playgroud)

我将SortableDateStart设置为计算列,以获取DateStart smalldatetime列并将其转换为bigit进行排序.它需要一个ISO8601日期(专为xml使用而设计,也可以方便排序)并替换T,:和 -

(replace(replace(replace(CONVERT([varchar](16),[DateStart],(126)),'T',''),'-',''),':',''))
Run Code Online (Sandbox Code Playgroud)

这有点难看.有一个更好的方法吗?我也愿意采用更好的方法来处理这种动态排序.

编辑:测试数据设置

DECLARE @Temp TABLE
(
[Rank] int,
[Title] nvarchar(100),
[DateStart] datetime
)

INSERT into @Temp
SELECT 1, 'title1', '1/1/2010 10:01:00AM'
UNION
SELECT 2, 'atitle1', '1/1/2010 10:03:00AM'
UNION
SELECT 3, 'title1', '1/1/2010 10:10:00AM'
UNION
SELECT 4, 'btitle1', '1/1/2010 10:04:00AM'
UNION
SELECT 10, 'title1', '1/1/2010 10:07:00AM'
UNION
SELECT 11, 'dtitle1', '1/1/2010 10:09:00AM'
UNION
SELECT 12, 'ctitle1', '1/1/2010 10:00:01AM'
UNION
SELECT 13, 'title1', '1/1/2010 10:10:00AM'

DECLARE @RankTypeID tinyint
--SET @RankTypeID = 0 -- rank
--SET @RankTypeID = 1 -- date start asc
SET @RankTypeID = 2 -- date start desc
--SET @RankTypeID = 3 -- title

SELECT 
    [Rank],
    [DateStart],
    [Title]
FROM
    @Temp
ORDER BY
    Case @RankTypeID
      When 0 Then [Rank]
      When 1 Then Cast([DateStart] As sql_variant)
      When 3 Then [Title]
      else null
    End,      
    Case @RankTypeID
      When 2 Then Cast([DateStart] As sql_variant)
    End DESC
Run Code Online (Sandbox Code Playgroud)

Den*_*eev 7

尝试这样的事情

ORDER BY
    Case Parent.RankTypeID
      When 0 Then dbo.Folders.Rank
      When 1 Then dbo.Documents.DateStart
      When 3 Then Cast(dbo.Documents.Title as sql_variant)
      else null
    End,      
    case Parent.RankTypeID
      when 2 Then dbo.Documents.DateStart
    end desc
Run Code Online (Sandbox Code Playgroud)

更新.

不,你不需要施展任何东西.这是测试数据的完整解决方案.

order by 
case @RankTypeID when 0 then [Rank] else null end,      
case @RankTypeID when 1 then [DateStart] else null end,
case @RankTypeID when 2 then [DateStart] else null end desc,
case @RankTypeID when 3 then [Title] else null end 
Run Code Online (Sandbox Code Playgroud)