2010-07-22 13 views
17

İki tablom var. Onları en sağdaki tabloda her kayıt için sağdaki tabloda sadece bir kaydın döndürüleceği şekilde birleştirmek istiyorum. Aşağıda bir örnek ekledim. Gerçek veriler yaklaşık 4M satır olduğu için alt sorgulardan ve geçici tablolardan kaçınmak istiyorum. Ayrıca, en sağdaki tabloda hangi kaydın eşleştirildiği, bir veya hiç eşleşmediği sürece umrumda değil. Teşekkürler!MySQL JOIN sorgusu yardımı: En soldaki tablodaki her satır için en sağdaki tablodan yalnızca bir satır döndürme

tablo kullanıcıları:

------------- 
| id | name | 
------------- 
| 1 | mike | 
| 2 | john | 
| 3 | bill | 
------------- 

tablo işlemleri:

--------------- 
| uid | spent | 
--------------- 
| 1 | 5.00 | 
| 1 | 5.00 | 
| 2 | 5.00 | 
| 3 | 5.00 | 
| 3 | 10.00 | 
--------------- 

beklenen çıkışı:

--------------------- 
| id | name | spent | 
--------------------- 
| 1 | mike | 5.00 | 
| 2 | john | 5.00 | 
| 3 | bill | 5.00 | 
--------------------- 
+0

Neden herkes user.id (birincil anahtar) ve user.name ile gruplanıyor? Birincil anahtarla gruplandırdıktan sonra gerçekten başka bir şeye ihtiyacınız olmaz. Bir şeyi mi özledim yoksa hepimiz sadece @OMG Ponies'i mi kopyalarız? – TheJacobTaylor

+2

@ TheJacobTaylor: Standart SQL, GROUP BY'de toplanmış olmayan sütunları dahil etmenizi gerektirir. ANSI standardı gereksiz alt gruplar varsa tüm sütunları tanımlamayı desteklemez - MySQL bunu destekler, ancak diğer birçok veritabanında çalışmaz. –

+2

@TheJacobTaylor: MySQL, tüm gruplama sütunlarını gerektirmez; Hemen hemen her DBMS yapar ve SQL standardını yapar. –

cevap

33

Kullanım:

SELECT u.id, 
     u.name, 
     MIN(t.spent) AS spent 
    FROM USERS u 
    JOIN TRANSACTIONS t ON t.uid = u.id 
GROUP BY u.id, u.name 

Bunun yalnızca en az bir İŞLEMLER kaydına sahip olan kullanıcıları döndüreceğini unutmayın. Eğer geri almak belirli bir satır umurumda değil ise

SELECT u.id, 
      u.name, 
      COALESCE(MIN(t.spent), 0) AS spent 
    FROM USERS u 
LEFT JOIN TRANSACTIONS t ON t.uid = u.id 
GROUP BY u.id, u.name 
+0

+1 nice, – northpole

+0

Ah ile bir çözüm bulmaya çalışıyordum! Tabii ki. Bazen çok miyop olurum. Bir soru bir yana, MySQL'in daha önceki sürümlerinde JOIN bu doğal olarak yoktu? –

+0

Evet, buna sol birleştirme denir. :) Sağ katılma bir maçı zorlayacaktır. Sol birleşmelerde kibritler yer alacak, ancak bunlara ihtiyaç duyulmayacaktır. – TheJacobTaylor

2

: Kullanım - Eğer destekleyen kayıtları yanı sıra yapanlar yok kullanıcıları görmek istiyorsanız.

select id, name, spent 
from users 
left join transactions on users.id = transactions.uid 
group by id 

Bu, kullanıcı başına bir satır döndürecektir. İlk eşleştirilen işlem olacak.

Alkış, Jacob

0

Benim özür Esasında bu soruya cevap vermezse. Hangi kullanıcıların en az bir işlemi olduğunu görmeye çalışıyorsunuz gibi görünüyor. Bunu yapmak ve bu süreçte her kullanıcı böyle bir şey yaparak harcamış ne kadar görebiliyordu:

 
SELECT 
    u.id, 
    u.name, 
    SUM(t.spent) AS total 
FROM 
    USERS u 
    INNER JOIN TRANSACTIONS t 
     ON t.uid = u.id 
GROUP BY 
    u.id 
    , u.name 
+0

Özellikle bir ya da hiç eşleşmedikleri soruda belirtilirler. – TheJacobTaylor

+0

Hata! "Bir veya daha fazla" – wshato

1

makul cevaplar bir dizi, eşdeğer bir son soru için SO 3305709 bakınız. Burada belirtilen DBMS Postgres, ancak burada farklılıklar göz ardı edilebilir.

+1

"DISTINCT ON" sadece Postgres tarafından desteklenir ve DISTINCT, kullanıcı başına farklı "harcanan" değerlerle birden fazla satır döndürür. –

İlgili konular