2010-01-15 26 views
22

Tôi đã tìm kiếm trang web này rộng rãi nhưng không thể tìm thấy giải pháp.Làm cách nào tôi có thể CHỌN nhiều cột trong một TRƯỜNG HỢP KHI NÀO trên SQL Server?

Dưới đây là ví dụ về truy vấn của tôi:

SELECT 
    ActivityID, 

    Hours = (CASE 
       WHEN ActivityTypeID <> 2 THEN 
        FieldName = (Some Aggregate Sub Query), 
        FieldName2 = (Some other aggregate sub query) 
       WHEN ActivityTypeID = 2 THEN 
        FieldName = (Some Aggregate Sub Query with diff result), 
        FieldName2 = (Some Other Aggregate Sub Query with diff result) 
      END) 

rõ ràng Tôi đi ra rất nhiều truy vấn, tôi chỉ muốn để xem nếu nó có thể.

Tôi biết tôi có thể chỉ cần thực hiện "TRƯỜNG HỢP" hai lần nhưng tôi sẽ hỏi ...

Cảm ơn!

+0

Câu hỏi liên quan, nhưng KHÔNG trùng lặp là http://stackoverflow.com/q/13713316/2420536 –

Trả lời

26

Vấn đề là tuyên bố CASE sẽ không hoạt động theo cách bạn đang cố gắng sử dụng. Bạn chỉ có thể sử dụng nó để chuyển đổi giá trị của một trường trong truy vấn. Nếu tôi hiểu những gì bạn đang cố gắng để làm, bạn có thể cần điều này:

SELECT 
    ActivityID, 
    FieldName = CASE 
        WHEN ActivityTypeID <> 2 THEN 
         (Some Aggregate Sub Query) 
        ELSE 
        (Some Aggregate Sub Query with diff result) 
       END, 
    FieldName2 = CASE 
        WHEN ActivityTypeID <> 2 THEN 
         (Some Aggregate Sub Query) 
        ELSE 
        (Some Aggregate Sub Query with diff result) 
       END 
12

Không, CASE là một hàm và chỉ có thể trả về một giá trị. Tôi nghĩ rằng bạn sẽ phải sao chép logic CASE của bạn.

Tùy chọn khác sẽ là bọc toàn bộ truy vấn bằng IF và có hai truy vấn riêng biệt để trả lại kết quả. Nếu không nhìn thấy phần còn lại của truy vấn, thật khó để nói nếu điều đó có hiệu quả với bạn.

1

"Case" có thể trở lại giá trị duy nhất mà thôi, nhưng bạn có thể sử dụng loại phức tạp:

create type foo as (a int, b text); 
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*; 
+2

Tôi nghĩ điều đó có thể xảy ra trong Postgres, chứ không phải sql-server (câu hỏi được gắn thẻ) – dsz

0

Trên thực tế bạn có thể làm nó.

Mặc dù, một người nào đó cần lưu ý rằng việc lặp lại các tuyên bố CASE không phải là điều xấu. Trình tối ưu hóa truy vấn của SQL Server đủ thông minh để không thực hiện CASE hai lần để bạn không bị ảnh hưởng bởi vì điều đó.

Thêm vào đó, ai đó có thể sử dụng logic sau đây để không lặp lại CASE (nếu nó phù hợp với bạn ..)

INSERT INTO dbo.T1 
(
    Col1, 
    Col2, 
    Col3 
) 
SELECT 
    1, 
    SUBSTRING(MyCase.MergedColumns, 0, CHARINDEX('%', MyCase.MergedColumns)), 
    SUBSTRING(MyCase.MergedColumns, CHARINDEX('%', MyCase.MergedColumns) + 1, LEN(MyCase.MergedColumns) - CHARINDEX('%', MyCase.MergedColumns)) 
FROM 
    dbo.T1 t 
LEFT OUTER JOIN 
(
    SELECT CASE WHEN 1 = 1 THEN '2%3' END MergedColumns 
) AS MyCase ON 1 = 1 

này sẽ chèn các giá trị (1, 2, 3) cho mỗi bản ghi trong bảng T1. Điều này sử dụng dấu phân tách '%' để tách các cột đã hợp nhất. Bạn có thể viết chức năng tách riêng của mình tùy thuộc vào nhu cầu của bạn (ví dụ: để xử lý bản ghi trống hoặc sử dụng dấu phân cách phức tạp cho các trường varchar, v.v.). Nhưng logic chính là bạn nên tham gia câu lệnh CASE và chọn từ tập hợp kết quả của phép nối bằng cách sử dụng logic phân tách.

Các vấn đề liên quan