2009-08-07 73 views

回答

15
ORDER BY 
    CASE WHEN @switch = 0 THEN Field1 END, 
    CASE WHEN @Switch = 1 THEN Field2 END 
+1

这只适用于Field1和Field2属于同一类型。 – edosoft 2009-08-07 11:41:34

+1

你可以把它写成一个case表达式...... CASE WHEN @ switch = 0 THEN Field1 WHEN @ switch = 1 THEN Field2 END – pjp 2009-08-07 11:47:27

+2

如果每个CASE都有一个THEN子句,则不必担心该字段的类型是。 – 2009-08-07 11:56:59

3

原始方法:

IF @switch = 1 
    BEGIN 
    SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY acct_nbr 
    END 
ELSE 
    BEGIN 
    SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY acct_name 
    END 

你也应该能够使用CASE..WHEN我想:

SELECT 
    acct_nbr, 
    acct_name 
FROM 
    acct 
ORDER BY 
    CASE @switch 
    WHEN 1 THEN acct_nbr 
    WHEN 0 THEN acct_name 
    END 
2

我不确定你可以吗?我最终会做这样的:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     if @switch 
     begin 
      SELECT 
        acct_nbr, 
        acct_name 
      FROM 
        acct 
      ORDER BY 
        acct_nbr 
     end 
     else 
     begin 
      SELECT 
        acct_nbr, 
        acct_name 
      FROM 
        acct 
      ORDER BY 
        acct_name 
     end 
    END 
GO 
+1

您可以通过在ORDER BY用CASE语句做到这一点,但如果查询是配备充分复杂,你的方法会更快。 – 2009-08-07 11:28:06

0
SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY case @switch when 1 then acct_name else acct_nbr end 
+0

这只适用于acct_nbr和acct_name具有相同数据类型或可相互转换的情况。 – edosoft 2009-08-07 11:30:21

+0

是的,但它是一种有用的技术。 – 2009-08-07 11:59:34

1

我想你可以在参数更改为int,并排序与序数列:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @ordinal AS INT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY @Ordinal 

    END 
GO 

这将引发友好的错误(SQL2005):

消息1008,级别16,状态1,第4行 由 ORDER BY鉴定号1的SELECT项目包含变量 作为识别 列表位置的表达式的一部分。当通过引用列名称的表达式 进行排序时,变量仅允许使用 。

周围的Googling发现this solution here(SQL 2005年及以上):

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY CASE 
      WHEN @switch = 0 THEN (RANK() OVER (ORDER BY acct_nbr, acct_name)) 
      WHEN @switch = 1 THEN (RANK() OVER (ORDER BY acct_name, acct_nbr)) 
     END 
GO 
0

最简洁的方法是:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY 
       case @switch 
        when 1 then acct_nbr 
        when 0 then acct_name 
       end 

    END 
GO 

这可能会导致较大的一个贫穷的执行计划表,或者如果acc-nbr是一个int并且acct-name是一个varchar,它可能根本不起作用。

在IF/ELSE语句中包装两个单独的查询可能对较大的数据集执行明显更好的操作,或者如果两列的数据类型不同,则它们是唯一可行的方法。

3

的一种方法是建立查询是这样的:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
DECLARE 
@SQL nvarchar(max) 


    SET @SQL N'SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY ' 

if(@switch) 
BEGIN 
    @SQL = @SQL + ' acct_nbr ' 
END 
ELSE 
BEGIN 
    @SQL = @SQL + ' acct_Name ' 
END 

Exec SP_ExecuteSQL @SQL