Tại sao Full Outer Tham gia này không hoạt động?


10

Tôi đã sử dụng Full Outer Joins trước đây để có kết quả mong muốn, nhưng có lẽ tôi không hiểu đầy đủ về khái niệm này vì tôi không thể thực hiện được những gì nên tham gia đơn giản.

Tôi có 2 bảng (mà tôi gọi là t1 và t2) với 2 trường mỗi bảng:

t1

Policy_Number Premium
101             15
102              7
103             10
108             25
111              3

t2

Policy_Number   Loss
101              5
103              9
107              20

Những gì tôi đang cố gắng làm là nhận được tổng phí và tổng thiệt hại từ cả hai bảng và cả Chính sách_Nội số. Mã tôi đang sử dụng là:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by t1.policynumber

Đoạn mã trên sẽ trả về tổng số chính xác nhưng nó sẽ nhóm tất cả các bản ghi trong đó không có kết quả trùng khớp chính sách trong "NULL" chính sách số.

Tôi muốn kết quả của tôi trông như thế này

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

Vân vân.....

Tôi không muốn một kết quả hiển thị số chính sách NULL như được hiển thị bên dưới (vì không có thứ gọi là chính sách NULL. Đây chỉ là tổng số khi số chính sách từ cả hai bảng không khớp):

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

Nếu tôi chọn và nhóm theo t2.policy_number thay vì t1.policy_number thì tôi nhận được một cái gì đó như dưới đây như một bản ghi.

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

Một lần nữa, tôi không phiền khi thấy NULL dưới Prem_Sum hoặc dưới Loss_sum nhưng tôi không muốn có NULL theo Chính sách_Number. Tôi muốn kết quả của tôi là một cái gì đó như

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

Vân vân.....

Tôi nghĩ rằng sự tham gia bên ngoài đầy đủ sẽ thực hiện điều này nhưng tôi đoán tôi đang thiếu một cái gì đó. Tôi đã nghĩ có lẽ tôi có thể chọn và nhóm theo cả t1.policy_number và t2.policy_number làm truy vấn phụ và sau đó có thể thực hiện CASE trong truy vấn bên ngoài hoặc một cái gì đó ??? Tôi không nghĩ nó nên phức tạp như vậy.

Bất kỳ ý tưởng hoặc lời khuyên?

Câu trả lời:


8

Bạn nên thực hiện một cách không chính xác trên cả hai chính sách để bạn có thể nhóm đúng.

Vì là tham gia ngoài, nên có khả năng một bên tham gia là NULL trong khi vẫn có dữ liệu.

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, isnull(t1.policynumber, t2.policynumber)
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by isnull(t1.policynumber, t2.policynumber)

... có nghĩa là null được xử lý như các giá trị của SQL, đó là lý do tại sao bạn cần ISNULL (). Đây là lý do tại sao SQL rất tệ miệng. Tuy nhiên tôi vẫn sử dụng nó hàng ngày.
Paul-Sebastian Manole

4

Việc tham gia bên ngoài đầy đủ sẽ tạo ra cấu trúc bản ghi mà bạn cần, nhưng nó sẽ không đưa chính sách số 107 vào Bảng 1 cho bạn.

Tôi nghĩ những gì bạn cần là một cái gì đó dọc theo dòng

select coalesce(t1.policy_number, t2.policy_number) as PolicyNumber, 
sum(t1.premium) as PremSum, sum(t2.loss) as LossSum
from t1 full outer join t2 on t1.policy_number = t2.policy_number
group by coalesce(t1.policy_number, t2.policy_number)

2

Để cung cấp thêm một chút thông tin về lý do tại sao truy vấn cụ thể của bạn không hoạt động. Mã bắt đầu của bạn là:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber 
from t1 full outer join t2 on t1.policynumber = t2.policynumber 
group by t1.policynumber 

Thoạt nhìn, điều này có vẻ như nó nên hoạt động. Tuy nhiên, lưu ý rằng cột thứ ba được chỉ định là t1.policynumber. Đây cũng là cột nhóm duy nhất. Do SQL Server này chỉ nhìn thấy các giá trị trong t1, để lại bất kỳ giá trị nào không nằm trong t1 là null (bởi vì, hãy nhớ rằng, đây là một phép nối ngoài đầy đủ). Mã isnull (t1.policynumber, t2.policynumber) sẽ cung cấp cho bạn tất cả các giá trị không null trong t1, sau đó sử dụng các giá trị trong t2.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.