2011-09-01 30 views
21

Tôi muốn có thể tham gia bên trong hai bảng dựa trên kết quả của một biểu thức.Tham gia bên trong có điều kiện

Những gì tôi đã cố gắng cho đến nay:

INNER JOIN CASE WHEN RegT.Type = 1 THEN TimeRegistration ELSE DrivingRegistration AS RReg 
ON 
RReg.RegistreringsId = R.Id 

Trung Đoàn là một tham gia tôi đã thực hiện ngay trước khi tham gia này:

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 

SQL-Kịch bản này không hoạt động.

Vì vậy, tất cả trong tất cả, nếu Type là 1, thì nó sẽ tham gia trên bảng TimeRegistration khác nên tham gia trên DrivingRegistration.

Giải pháp:

Trong tuyên bố chọn của tôi, tôi biểu diễn tham gia sau đây:

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
LEFT OUTER JOIN TimeRegistration AS TReg ON TReg.RegistreringsId = R.Id AND RegT.Type = 1 
LEFT OUTER JOIN DrivingRegistration AS DReg ON DReg.RegistreringsId = R.Id AND RegT.Type <>1 

Sau đó, tôi thay đổi nội dung của tôi where-clause để sản xuất các chính xác, tùy thuộc vào RegType, như thế này:

WHERE (CASE RegT.Type WHEN 1 THEN TReg.RegistreringsId ELSE DReg.RegistreringsId END = R.Id) 
+0

Bạn không thể làm điều đó như thế! Không thể sử dụng 'CASE' để tự động hoán đổi vào và ra các phần ngẫu nhiên của truy vấn. Những bảng này có cùng cấu trúc không? –

+0

Bạn có gặp lỗi không? Nếu vậy, nó là cái gì? – AndrewC

Trả lời

18

Hãy thử đặt cả hai bảng trong truy vấn sử dụng LEFT JOIN của

LEFT JOIN TimeRegistration TR ON r.rid = TR.Id AND RegT.type =1 
LEFT JOIN DrivingRegistration DR ON r.rid = DR.Id AND RegT.type <>1 

Bây giờ, trong bạn chọn khoản, sử dụng

CASE RegType.Type WHEN 1 THEN TR.SomeField ELSE DR.someField END as SomeField 

Các tùy chọn khác là sử dụng SQL động

+0

Có vẻ như những tư duy tuyệt vời nghĩ giống David, bạn chỉ cần gõ nhanh hơn .... – Sparky

+0

Ngón tay Ninja ... – David

+0

Tuyệt vời, cả hai đề xuất của Sparky và David đều giúp! Sẽ chỉnh sửa câu hỏi của tôi cho những gì tôi đã làm để làm cho nó hoạt động. – KristianB

8

Có thể bạn cần thực hiện hai lần kết nối trái, một vào TimeRegistration và một vào DrivingRegistration, và trở về các lĩnh vực mà bạn muốn từ thích hợp tham gia bàn một cái gì đó như thế này:

LEFT JOIN TimeRegistration ON TimeRegistration.RegistreringsId = R.Id 
LEFT JOIN DrivingRegistration ON DrivingRegistration.RegistreringsId = R.Id 

và bạn chọn tuyên bố sẽ là một cái gì đó như thế này:

SELECT CASE WHEN RegT.Type = 1 THEN TimeRegistration.Foo ELSE DrivingRegistration.Bar END 

Tôi thích những gì bạn' đang cố gắng làm, nhưng tôi không nghĩ rằng SQL là thông minh.

1
SELECT 
    R.foo, tr.bar 
FROM 
    SomeTable AS R 
    INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
              AND RegT1.Type = 1 
    INNER JOIN TimeRegistration AS tr ON /* whatever */ 

UNION 

SELECT 
    R.foo, dr.bar 
FROM 
    SomeTable AS R 
    INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
              AND RegT1.Type = 2 
    INNER JOIN DrivingRegistration AS dr ON /* whatever */ 
+0

+1 mặc dù có thể sẽ cần phải là 'UNION ALL'. Nếu các bảng là Union tương thích, chúng có thể ở trong một CTE với một cột 'type' để tránh lặp lại logic' JOIN' mặc dù không chắc chắn kế hoạch thực thi sẽ trông như thế nào. –

+0

@Martin: Với các chỉ mục phù hợp, hai lần tham gia sẽ nhanh hơn rất nhiều. Tôi giả định kể từ khi hai bảng mục tiêu khác nhau, một UNION ALL sẽ không cần thiết. – Tomalak

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