SQL Server动态Order By在查询时,不同的数据类型

时间:2009-10-01 12:59:15

标签: sql-server sql-server-2000

SQL Server 2000

我有一个像

这样的查询
SELECT DISTINCT A.COLUMN1, B.COLUMN2 FROM TABLEA A, TABLEB B WHERE 
A.KEY_ID = B.FK_ID

ORDER BY CASE @ORDER_NAME
         WHEN 'COL1' THEN COLUMN1
         WHEN 'COL2' THEN COLUMN2
         ELSE
         COLUMN2
         END ASC

这里A.COLUMN1是varchar(50),B.COLUMN2是datetime。当@ORDER_NAME的值为'COL2'时,此查询非常有效,即当order by是datetime类型时,但是当我使用'COL1'时,它会给出错误'语法错误从字符串转换datetime。'

我认为这是因为SQL Server正在尝试将所有列转换为datetime类型。但我找不到动态排序列的替代语法。由于性能问题,EXEC是不可能的

我需要提一下,我正试图避免分支,否则上述情况也可以通过IF ELSE条款完成。

4 个答案:

答案 0 :(得分:7)

没有任何数据类型转换问题的版本:

SELECT  DISTINCT 
        A.COLUMN1, 
        B.COLUMN2 
FROM    TABLEA A, 
        TABLEB B 
WHERE   A.KEY_ID = B.FK_ID
ORDER BY 
        CASE @ORDER_NAME WHEN 'COL1' THEN COLUMN1 ELSE NULL END,
        CASE @ORDER_NAME WHEN 'COL2' THEN COLUMN2 ELSE NULL END

答案 1 :(得分:0)

这应该有效:

IF @ORDER_NAME = 'COL1'
BEGIN
    SELECT DISTINCT A.COLUMN1, B.COLUMN2 FROM TABLEA A, TABLEB B WHERE A.KEY_ID = B.FK_ID
    ORDER BY COLUMN1 ASC
END

ELSE
BEGIN
    SELECT DISTINCT A.COLUMN1, B.COLUMN2 FROM TABLEA A, TABLEB B WHERE A.KEY_ID = B.FK_ID
    ORDER BY COLUMN2 ASC
END

答案 2 :(得分:0)

您可以执行以下操作:

SELECT DISTINCT A.COLUMN1, B.COLUMN2, 
    CASE @ORDER_NAME
        WHEN 'COL1' THEN COLUMN1
        ELSE CONVERT(COLUMN2,  --convert to nvarchar in a way that orders properly, cant remember off the top of my head 
    END SortCol
FROM TABLEA A, TABLEB B
WHERE A.KEY_ID = B.FK_ID
ORDER BY SortCol ASC

更新

实际上你可能在查询中将日期转换为varchar并且它可以正常工作,我刚刚完成它,就像之前的那样,来自xquery表达式的排序列就这样发布了。

答案 3 :(得分:0)

将它们全部转换为varchar:

SELECT DISTINCT A.COLUMN1, B.COLUMN2 FROM TABLEA A, TABLEB B WHERE 
A.KEY_ID = B.FK_ID

ORDER BY CASE @ORDER_NAME
         WHEN 'COL1' THEN CONVERT(varchar(nn),COLUMN1)
         WHEN 'COL2' THEN CONVERT(varchar(23),COLUMN2,121)
         ELSE
         CONVERT(varchar(23),COLUMN2,121)
         END ASC

然后你甚至可以按多列排序,这在排序依据列中有许多类似的值时很好:

SELECT DISTINCT A.COLUMN1, B.COLUMN2 FROM TABLEA A, TABLEB B WHERE 
A.KEY_ID = B.FK_ID

ORDER BY CASE @ORDER_NAME
         WHEN 'COL1' THEN CONVERT(varchar(nn),COLUMN1)+CONVERT(varchar(23),COLUMN2,121)
         WHEN 'COL2' THEN CONVERT(varchar(23),COLUMN2,121)+RIGHT(REPLICATE('0',nn)+CONVERT(varchar(nn),COLUMN1),nn)
         ELSE CONVERT(varchar(23),COLUMN2,121)+RIGHT(REPLICATE('0',nn)+CONVERT(varchar(nn),COLUMN1),nn)
         END ASC