2012-01-24 27 views
6

Tôi có hai bảng như sau:giới hạn, sự lựa chọn của UNION lặp lại kiểm tra các cột

parameters1

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 

parameters2

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | mmm | 

Tôi thường JOIN tập kết quả của hai bảng này với UNION theo cách này:

SELECT cod, des 
FROM parameters1 
UNION 
SELECT cod, des 
FROM parameters2 

và tôi có được điều này tập kết quả:

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 
| 1 | mmm | 

Tôi muốn giới hạn kiểm tra chỉ đến cột cod trùng lặp UNION, vì vậy tôi muốn tránh điều đó là 1 cá tuyết được nhân đôi trong tập kết quả (khi có một kỷ lục với tên khác và cá tuyết giống nhau), tôi muốn lấy tên từ bảng đầu tiên (parameters1):

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 

CẬP NHẬT Nếu tôi loại bỏ các kỷ lục 1 từ parameters1 bảng (DELETE FROM parameters1 WHERE cod = 1) i nên có được điều này tập kết quả:

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | mmm | ---> FROM parameters2 
| 2 | bbb | 
| 3 | ccc | 

Có thể hạn chế việc kiểm tra trùng lặp của một UNION để chỉ có một lĩnh vực hoặc một số lĩnh vực? Làm sao ?

Giải pháp sẽ hoạt động trên môi trường đa dữ liệu (MSSQL, PostgreSQL, MySQL).

+0

thể trùng lặp của [SQL Server Liên minh riêng biệt cho một cột] (http://stackoverflow.com/questions/7338884/sql-server-distinct-union-for-one-column) – ruakh

+0

Xin giải thích logic tại sao hàng '(1, 'aaa')' được chọn trên hàng '(1, 'mmm')' ví dụ bởi vì '' aaa '<' mmm'', có lẽ? Câu trả lời được chấp nhận dường như chọn một hàng tùy ý. – onedaywhen

+0

Đó là logic mà tôi đã xác định bởi vì một bảng có quyền ưu tiên ... – aleroot

Trả lời

9
SELECT cod, des 
FROM parameters1 p1 
UNION ALL 
SELECT cod, des 
FROM parameters2 p2 
WHERE NOT EXISTS (
    SELECT 1 
    FROM parameters1 p1sub 
    WHERE p1sub.cod = p2.cod 
) 
+0

Giải pháp tuyệt vời, Cảm ơn bạn! – aleroot

+2

Đó là chính xác nhưng nó phải nhanh hơn với 'UNION ALL'. –

+0

@ypercube Rất tốt, không cần phải cố gắng lọc ra bất kỳ bản sao ở đây ... cập nhật. –

2

Giải pháp trong this link phải thích ứng với các môi trường đó, vì đó là SQL chuẩn (bạn có thể sử dụng ISNULL nếu không có COALESCE). Tôi không chắc chắn tính khả dụng của FULL OUTER JOIN là gì, nhưng cũng có sẵn trên cả ba nền tảng.

Trong trường hợp của bạn, giải pháp sẽ kết thúc tìm kiếm như:

SELECT p1.cod, ISNULL(p1.des, p2.des) AS des 
FROM parameters1 p1 
    FULL OUTER JOIN parameters2 p2 ON p1.cod = p2.cod 

... nhưng ... MySQL dường như không hỗ trợ FULL OUTER JOIN, vì vậy bạn có thể sử dụng thủ thuật khác trong trường hợp đó:

SELECT p1.cod, ISNULL(p1.des, p2.des) AS des 
FROM parameters1 p1 
    LEFT JOIN parameters2 p2 ON p1.cod = p2.cod 
UNION ALL 
SELECT p2.cod, p2.des 
FROM parameters2 p2 
    LEFT JOIN parameters1 p1 ON p1.cod = p2.cod 
WHERE p1.cod IS NULL 
+0

giải pháp không bao gồm các trường hợp tham số chỉ sống trong bảng thứ hai, đó là kết quả sẽ luôn giống như một lựa chọn đơn giản từ bảng đầu tiên – newtover

+0

Điểm tốt.Một FULL OUTER JOIN nên sửa lỗi đó. – mwigdahl

+0

Nó không hoạt động bởi vì nếu tôi loại bỏ các bản ghi từ các thông số 1 tôi không nhận được bất cứ điều gì ... Xem câu hỏi được cập nhật, và xin lỗi vì không được chính xác nhiều trong câu hỏi. – aleroot

0

Thay đổi truy vấn kết hợp thứ hai để chỉ nhận tham số2 trong đó tham số2.id không có trong tham số1.

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