2009-08-07 39 views
6

Tôi đang cố gắng tạo một thủ tục được lưu trữ có một tham số bit mà nếu đúng đơn đặt hàng của một cột và nếu sai đơn đặt hàng của cột khác. Làm thế nào tôi sẽ thực hiện điều này?IF tuyên bố trong ORDER BY khoản của một tuyên bố SELECT trong một SQL Server lưu trữ thủ tục

Dưới đây là những gì tôi có cho đến nay

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     SELECT 
      acct_nbr, 
      acct_name 
     FROM 
      acct 
     ORDER BY 

    END 
GO 

Trả lời

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

Điều này chỉ hoạt động khi Field1 và Field2 có cùng loại. – edosoft

+1

Bạn có thể viết biểu thức này dưới dạng một trường hợp ... TRƯỜNG HỢP KHI @ switch = 0 THEN Field1 WHEN @ switch = 1 THEN Field2 END – pjp

+2

Nếu mỗi CASE có một mệnh đề THEN, bạn không cần phải lo lắng về loại trường nào là. –

3

Một cách thô:

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 

Bạn cũng sẽ có thể sử dụng CASE..WHEN Tôi nghĩ:

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

Tôi không thực sự chắc chắn bạn có thể? Tôi muốn kết thúc làm điều này:

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

Bạn có thể làm điều đó bằng cách sử dụng một tuyên bố CASE trong ORDER BY, nhưng nếu truy vấn là sufficently phức tạp, phương pháp của bạn sẽ nhanh hơn. –

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

Điều này chỉ hoạt động khi acct_nbr và acct_name có cùng kiểu dữ liệu hoặc có thể chuyển đổi được với nhau. – edosoft

+0

Đúng, nhưng đó là một kỹ thuật hữu ích. –

1

tôi nghĩ bạn có thể thay đổi các tham số để một int, và sắp xếp theo cột với thứ tự rằng:

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

    END 
GO 

này ném một lỗi đẹp (SQL2005):

Msg 1008, Level 16, State 1, Line 4 SELECT mục xác định bởi các ORDER bY số 1 chứa biến số như một phần của biểu thức xác định vị trí cột. Các biến chỉ được phép là khi được sắp xếp theo một biểu thức tham chiếu đến tên cột.

Googling xung quanh thấy this solution here (SQL 2005 trở lên):

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

Phương pháp cô đọng nhất là:

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 

này có thể dẫn đến một kế hoạch thực hiện kém cho lớn hơn bảng, hoặc nó có thể không hoạt động ở tất cả nếu acc-nbr là một int và acct-name là một varchar.

Gói hai truy vấn riêng biệt trong báo cáo IF/ELSE có thể hoạt động tốt hơn đáng kể cho tập dữ liệu lớn hơn hoặc là cách tiếp cận khả thi duy nhất nếu kiểu dữ liệu của hai cột khác nhau.

3

Một cách là để xây dựng một cái gì đó Query như thế này:

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 
Các vấn đề liên quan