2012-02-08 14 views
6

Tôi có một câu hỏi như sau:đơn giản hóa câu lệnh SQL bằng cách sử dụng CTE

SELECT A.a, A.b, B.c, 
(CASE WHEN ... THEN ... ELSE ... END) AS CalculatedValue, 
B.d 
FROM dbo.TableA A INNER JOIN 
     dbo.TableB B ON (...) 
WHERE (CASE WHEN ... THEN ... ELSE ... END) BETWEEN @DayStart AND @DayEnd 
GROUP BY A.a, (CASE WHEN ... THEN ... ELSE ... END), B.c 

để tránh lặp lại nhiều lần cùng một biểu hiện chính xác: (CASE WHEN ... THEN ... ELSE ... END) tôi muốn xác định một CTE và truy vấn bảng như sử dụng trong các lựa chọn, ở đâu và nhóm bởi sự biểu hiện CalculatedValue

tiếc là điều này không làm việc vì nhu cầu chọn để đã bao gồm group by khi tạo CTE

có bất kỳ cách khác tôi có thể sử dụng để không lặp lại các CASE WHEN... rất nhiều lần?

Trả lời

7

Sử dụng CROSS APPLY, có thể được sử dụng để xác định các lĩnh vực aliased và sau đó giới thiệu cho họ:

SELECT A.a, 
     A.b, 
     B.c, 
     CalculatedValue, 
     B.d 
FROM  
     dbo.TableA A 
INNER JOIN 
     dbo.TableB B 
     ON (...) 
CROSS APPLY 
     (SELECT (CASE WHEN ... THEN ... ELSE ... END)) CxA(CalculatedValue) 
WHERE CalculatedValue BETWEEN @DayStart AND @DayEnd 
GROUP BY A.a, CalculatedValue, B.c 

Các CxA chỉ là một bí danh và bạn có thể đặt tên cho nó bất cứ điều gì bạn muốn.

+0

Cảm ơn JNK, điều này đã giải quyết được vấn đề, cùng thời gian thực hiện nhưng cách mã sạch hơn trước, +1 và cờ xanh ;-) –

+0

Rất vui được trợ giúp! Gần đây tôi chỉ biết được điều này về bản thân và nó đã làm rất nhiều thứ đơn giản hơn. – JNK

+0

Nó thực sự thú vị khi đóng gói logic chung trong các hàm có giá trị bảng. Truy vấn có thể kết thúc đọc 'bảng CROSS ÁP DỤNG udf1 CROSS ÁP DỤNG udf2 CROSS ÁP DỤNG udf3' và tất cả các 'bình thường' SQL ẩn đi! – MatBailie

0

Ở trên, tôi nghĩ bạn chỉ có thể làm hai lớp CTE. Việc đầu tiên sẽ làm Tính toán cho tất cả, thứ hai sẽ chọn từ CTE đầu tiên và bộ lọc dựa trên giá trị được tính toán. Truy vấn cuối cùng sẽ tham gia vào CTE lớp thứ hai.

Chỉ là một ý nghĩ.