2011-08-18 17 views
5

Bir n: n veri setim var (örneğin, 'programcılar' ve 'diller'. Programcılar birçok dilde kod yazıyor ve bir dil birçok kişi tarafından kullanılabilir programcılar). Bu veriler bir tablodoldur. Programlama_addeleriMYSQL ifadesi n: n tablosundan grup seçmek için kullanılır

Tüm dil gruplarını kodlayan programcıları nasıl hızla seçerim? Bu kafa karıştırıcı ise

fazla bilgi: C++, Pascal ve Ruby

Jon kodları. Joe, C++ ve Ruby'de kodlar. Ruby ve Pascal'da Moe kodları. C++ ve Pascal'da Steve Kodları.

Söz konusu diller C++ ve Pascal ise, bu listeden Jon ve Steve'i isterim.

Bu kümenin boyutunun oldukça büyük olabileceğini unutmayın, bu nedenle tabloya kendiliğinden n kez katılmak istemiyorum.

+0

Sütun = "foo" AND column = "bar" türünde olan bu sorunun çok yanlış cevaplar yakaladığından mutlu veya üzgün olduğumdan emin değilim. – SingleNegationElimination

+0

Sadece bir tablo var mı yoksa bu senaryoda daha fazla tablo var mı? Ve sadece iki dil mi, yoksa filtreleyebileceğiniz değişken bir dil sayısı mı? – Thorin

+0

Bir tablo ve değişken sayıda dil. Ama sadece 4 veya daha az dil ele alınırsa kabul edilebilir. –

cevap

4

Not bu setin boyutu oldukça büyük alabilirsiniz, bu yüzden tabloyu katılmak istemiyorum: dinamik sorgu oluşturma ediyorsanız, aşağıdaki elbette daha da çabuk olacağını kendisi n kez.

Herhangi bir şekilde salladığınızda, her dil için bir katılım olacak. Başka bir değerin (dil) her biri için en az bir satır bulunan bir değer (programcı) arıyorsunuz. Bu, aynı tablonun N farklı perspektifini düşünmeniz gerektiği anlamına gelir.

Çoğu durumda, yalnızca birleştirme işlemini yapmanız sizin için en etkili olanıdır. Sonuç kümesi yeterince yoğunsa (gerçekten, programcıların çoğu python ve C++ konuşur), bazı zekice olabilirler. İlk disjunction sorgulamak ama benzersiz, ardından grup sonuçlanan ilişki programcısı tarafından ve çok az dilleri konuşan olanları süzmek ...

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 

Ama bu düzenli ol geride Hava' çok yönlü bağlı olacak birleşim söz konusu kesin veriler. Bu, en azından söz konusu dillerin sayısına bağlı olarak üretim sorguları gerektirme avantajına sahiptir.

+0

+1, birleştirmelerin muhtemelen çoğu zaman daha verimli olduğunu belirtmek için. Yine de, veri kümesinin ne kadar büyük olduğunu bilmek ilginç olurdu. – Thorin

+0

Veriler, yaklaşık 6000.000 programcı ve ~ 1800 "dilin" olduğu yaklaşık 550.000 satırdır. Performans bir sorundur, çünkü bu db'yi bir kerede 50 kez çalacaklar (bu sorgu idareli olarak kullanılır, ancak veritabanını 20 saniye boyunca kilitleyemiyorum). –

+0

Bu iyi bir cevap ... Sadece iç karartıcı. Verileri programlayıcı tarafından gruplandırmanın etkili bir yolu olmadığına şaşırdım ve daha sonra bir dizi n dilini kontrol etmek için sırayla her programcıya bakın. Verilerin büyüklüğü ile, bir 4x kendi kendine katılma delilik olurdu. –

-1

düzenleme: Bu ilk yanıtımdı ve soru için çalışmıyor. sadece bir kere her sonuç elde böylece

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

DISTINCT: tablo Programmers_Languages varsayarsak

iki VARCHAR sütun, tek denilen Programmer ve Languages adı verilen diğer sahiptir. Alfabetik olarak sıralanmasını istiyorsanız ORDER BY.


düzenlemek: Farklı sorgu, bu çalışır.

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

TokenMacGuy çok benzer bir şey ortaya çıktı gibi görünüyor. Dillerin ve dillerin sayısının başka bir kod tarafından bu sorguya ekleneceğini varsayalım.

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

Hayır. Bu, bu dillerden en az birini konuşan programcıları seçer, ancak corykendall, yalnızca hepsini konuşan programcıları üreten bir sorgu sordu. – SingleNegationElimination

+0

Bu işe yaramıyor - sadece 1 değil, tüm öğeleri eşleştiren bir insan listesine ihtiyacı var. –

+0

Mükemmel bir nokta, çocuklar, yorgun gözlerim "ve" bir "veya" olarak yanlış okuyorlar. Ayrıca, @corykendall, mükemmel soru! – Thorin

İlgili konular