2011-08-18 27 views
5

Tôi có một tập dữ liệu n: n (ví dụ: 'lập trình viên' và 'ngôn ngữ'. Lập trình viết mã bằng nhiều ngôn ngữ và nhiều ngôn ngữ có thể được nhiều người sử dụng lập trình viên). Dữ liệu này nằm trong một bảng programmers_languages ​​Câu lệnh MYSQL để nhanh chóng chọn nhóm từ n: n bảng

Làm cách nào để nhanh chóng chọn lập trình viên có mã trong tất cả các nhóm ngôn ngữ?

Thông tin khác nếu điều này gây nhầm lẫn:

Mã Jon trong C++, Pascal và Ruby. Joe mã trong C + + và Ruby. Mã Moe trong Ruby và Pascal. Steve mã trong C + + và Pascal.

Nếu bộ ngôn ngữ được đề cập là C++ và Pascal, tôi muốn Jon và Steve từ danh sách này.

Lưu ý rằng kích thước của tập hợp này có thể khá lớn, vì vậy tôi không muốn tham gia bảng tự n lần.

+0

Tôi không chắc chắn rằng tôi đang hạnh phúc hay buồn rằng câu hỏi này, mà là trong gia đình của 'cột =" foo "VÀ cột =" bar "' bắt rất nhiều câu trả lời sai. – SingleNegationElimination

+0

Chỉ có một bảng, hoặc có nhiều bảng trong kịch bản này không? Và nó chỉ là hai ngôn ngữ, hay là một số ngôn ngữ khác nhau mà bạn có thể lọc? – Thorin

+0

Một bảng và số lượng ngôn ngữ khác nhau. Nhưng nó sẽ được chấp nhận nếu nó chỉ xử lý 4 hoặc ít ngôn ngữ hơn. –

Trả lời

4

Lưu ý kích thước của bộ này có thể nhận được khá lớn, vì vậy tôi không muốn tham gia bảng để chính nó n lần.

Bất kỳ cách nào bạn lắc nó, sẽ có sự tham gia cho từng ngôn ngữ. Bạn đang tìm kiếm một giá trị (lập trình viên) mà có tồn tại ít nhất một hàng cho mỗi giá trị khác (ngôn ngữ). Điều đó có nghĩa là bạn cần phải suy nghĩ về N quan điểm khác nhau của cùng một bảng.

Trong hầu hết các trường hợp, có thể hiệu quả nhất để bạn thực hiện các phép nối. Nếu tập hợp kết quả là đủ dày đặc (thực sự, hầu hết các lập trình viên nói python và C++), bạn có thể dùng đến một số thông minh. Đầu tiên truy vấn có sự khác biệt, nhưng duy nhất, sau đó nhóm quan hệ kết quả của lập trình viên và lọc ra những người mà nói quá vài ngôn ngữ ...

SELECT programmer 
FROM (SELECT DISTINCT programmer, language 
     FROM speaks_table 
     WHERE language in ('C++', 'python')) AS disjunction 
GROUP BY disjunction.programmer 
HAVING count(disjunction.language) = 2 

Nhưng thời tiết này nhanh hơn so với một ol thường xuyên' Multiway join sẽ phụ thuộc vào dữ liệu chính xác được đề cập. Điều này ít nhất có lợi thế là không yêu cầu truy vấn sinh sản phụ thuộc vào số lượng ngôn ngữ được đề cập.

+0

+1 để chỉ ra rằng các kết nối có lẽ hiệu quả hơn hầu hết thời gian. Tuy nhiên, thật thú vị khi biết được tập dữ liệu lớn đến mức nào. – Thorin

+0

Dữ liệu khoảng 550.000 hàng, trong đó có ~ 6000 "lập trình viên" và ~ 1800 "ngôn ngữ". Hiệu suất là một vấn đề, vì sẽ có 50 người đánh db này cùng một lúc (truy vấn này được sử dụng một cách tiết kiệm, nhưng tôi không thể có nó khóa cơ sở dữ liệu trong 20 giây). –

+0

Đây là câu trả lời hay ... Chỉ là buồn. Tôi ngạc nhiên không có cách nào hiệu quả để nhóm dữ liệu theo lập trình viên, và sau đó xem xét từng lập trình viên để kiểm tra một bộ ngôn ngữ n. Với kích thước của dữ liệu, tự tham gia 4x sẽ mất trí. –

-1

chỉnh sửa: đây là câu trả lời đầu tiên của tôi và không hoạt động cho câu hỏi.

Giả sử bảng Programmers_Languages có hai VARCHAR cột, một gọi là Programmer và người kia gọi Languages:

SELECT DISTINCT Programmer 
FROM Programmers_Languages 
WHERE Language IN ('C++', 'Pascal') 
ORDER BY Programmer 

DISTINCT để bạn chỉ nhận được mỗi kết quả một lần. ORDER BY nếu bạn muốn nó được sắp xếp theo thứ tự bảng chữ cái.


chỉnh sửa: truy vấn khác nhau, công trình này.

SELECT Programmers 
FROM Programmers_Languages 
WHERE Languages IN ('C++', 'Pascal') 
GROUP BY Programmers 
HAVING COUNT(*) >= 2 
ORDER BY Programmers 

Có vẻ như TokenMacGuy đã đưa ra một cái gì đó rất giống nhau. Tôi giả định rằng danh sách các ngôn ngữ và số lượng ngôn ngữ sẽ được chèn vào trong truy vấn này bằng một số mã khác. Nếu bạn đang xây dựng các truy vấn tự động, sau đây sẽ là thậm chí nhanh hơn, tất nhiên:

SELECT DISTINCT Programmers 
FROM Programmers_Languages 
WHERE Languages = 'C++' 
AND Languages = 'Pascal' 
AND <...> 
ORDER BY Programmers 
+0

Không. Điều này chọn các lập trình viên nói ít nhất một trong những ngôn ngữ đó, nhưng corykendall yêu cầu một truy vấn chỉ tạo ra các lập trình viên nói tất cả chúng. – SingleNegationElimination

+0

Điều đó không có tác dụng - anh ấy cần danh sách những người phù hợp với TẤT CẢ các mục, không chỉ 1. –

+0

Điểm tuyệt vời, các bạn, đôi mắt mệt mỏi của tôi đã hiểu sai "và" là "hoặc". Ngoài ra, @corykendall, câu hỏi tuyệt vời! – Thorin

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