2012-07-02 25 views
7

Tôi có một bảng với hai cột:Mysql Chọn cặp đối ứng của hồ sơ, mà không cần bản sao

  1. Person_Id
  2. Person_Id mà lĩnh vực 1st id là trong hợp tác

tôi cần phải chọn tất cả cặp hợp tác, nó rất dễ dàng nhưng trong vấn đề là gì: bảng có dữ liệu như: 987 - 102, 103 - 104, 104 - 103, 21 - 102. Do kết quả với dữ liệu như vậy, tôi nên có 3 cặp hợp tác 987 - 102, 103-104, 21-102, như bạn thấy 103 - 104104 - 103 bản ghi có cùng logic, làm cách nào tôi có thể tránh sao chép chúng. Bất kỳ ý tưởng?

Xin cảm ơn và kính thư. Anton.

+0

Hiện chúng tôi cấu trúc bảng của bạn –

+0

Person_Id int (10), QUESTION_ID int (10) TEXT_ANSWER văn bản, tôi nghĩ rằng colomn thứ hai là không cần, bởi vì trong câu hỏi đó, tôi sử dụng nó trong mệnh đề WHERE –

Trả lời

10

Bạn có thể sử dụng MySQL của LEAST()GREATEST() chức năng, cùng với DISTINCT:

SELECT DISTINCT LEAST(a, b), GREATEST(a, b) FROM mytable 
+1

nếu bạn chỉ có cặp ' (2,1) 'nó sẽ xuất nó thành' (1,2) ' – alfasin

+1

@alfasin: Mô tả vấn đề ngụ ý chúng tương đương nhau. Nếu không, OP sẽ làm rõ cách thức mà nó đã được quyết định của '(103,104)' và '(104,103)' nên được giữ và loại bỏ. – eggyal

+0

@eggyall: bạn là chính xác, không có dấu hiệu nào được đưa ra về cách xác định được thực hiện rằng '(103,104)' nên được trả về thay vì '(104,103)'. Nhưng việc bảo quản thứ tự của các phần tử trong các "cặp" khác có thể quan trọng trong một số trường hợp. Ví dụ, nếu tập hợp kết quả này (truy vấn phụ) được nối với bảng một lần nữa, để lấy các cột khác từ hàng. Điểm mấu chốt là thứ tự của các phần tử trong cặp có thể là quan trọng (và chúng ta không được thông báo rằng nó không phải là.) Đặc tả này đưa ra một kết quả ví dụ. Truy vấn của bạn trả về kết quả khác với đặc tả. – spencer7593

3

Nếu giữ gìn trật tự của các yếu tố trong mỗi "cặp" là không quan trọng, xem câu trả lời từ eggyal. Truy vấn đó trả về tập hợp kết quả hơi khác so với kết quả bạn đã chỉ định, nó trả về cặp 102-987 thay vì 987-102. Nó cũng loại bỏ bất kỳ cặp "trùng lặp" nào xuất hiện trong bảng.

Nếu duy trì thứ tự của các phần tử trong mỗi cặp quan trọng và bạn muốn trả về "nhỏ hơn - lớn hơn" thay vì "lớn hơn - nhỏ hơn" khi cả hai cặp "phù hợp" đó hiện diện, bạn có thể sử dụng một cái gì đó như thế này:

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 

Để loại bỏ tất cả các cặp trùng lặp VÀ "phù hợp với" cặp, thêm một mệnh đề GROUP hoặc từ khóa DISTINCT, ví dụ như THEO

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 
GROUP BY c.col1, c.col2 

GHI CHÚ:

SQL Fiddle ở đây: http://sqlfiddle.com/#!2/1d9e7/1 và ở đây: http://sqlfiddle.com/#!2/1d9e7/2

Các toán tử so sánh không phải là null-an toàn, họ có thể không trả lại resultset bạn muốn khi một trong hai col1 hoặc col2 chứa giá trị NULL. (Truy vấn có thể được sửa đổi để xử lý các giá trị NULL cho col1 và/hoặc col2.) Khi được viết, cả hai truy vấn sẽ trả về, ví dụ, cả hai (1,NULL)(NULL,1) nếu các cặp "khớp" "đó nằm trong bảng. (Nó tóm tắt câu hỏi liệu bạn có muốn xem xét các giá trị NULL để khớp hay không.)

Cũng lưu ý, cả hai truy vấn sẽ trả về các hàng ở đó col1=col2.

Lưu ý truy vấn đầu tiên KHÔNG loại bỏ các hàng "trùng lặp" tồn tại trong bảng. Tức là, nếu một cặp "trùng lặp", ví dụ: (202,101) xuất hiện trong hai hàng khác nhau, thì cả hai hàng sẽ được trả về (trừ khi truy vấn trả về ít nhất một hàng có cặp "khớp": (101,202).)

Không rõ kết quả bạn muốn trả về trong những trường hợp đó, vì vậy truy vấn đầu tiên hiển thị mẫu để loại bỏ các hàng CHỈ (larger,smaller) khi cặp kết hợp (smaller,larger) nằm trong kết quả.

Truy vấn thứ hai loại bỏ TẤT CẢ các cặp trùng lặp và cặp "phù hợp".

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