2013-05-26 17 views
10

İki tablonun, ileti dizisinin ve iletinin var, Yapmak istediklerim, ileti dizisinden iletilere iç birleştirme yapmaktır. İşte Bir iç birleştirme ve maksimum kimlikle en yüksek ids'ı alın

benim sorgu: Şimdi her şey olması gerektiği gibi çalışır

SELECT 
    messages.msg, 
    messages.`read`, 
    conversations.userid, 
    conversations.contactid 

    FROM conversations 
     INNER JOIN messages ON 
     conversations.id = messages.convId 
    WHERE conversations.id IN(443,444) 

ama son şey iç birleşim i ı en yüksek almak istiyorum

conversations.id = messages.convId 

kullandığınız yere olmasıdır kimlikleri yalnızca, gibi:

AND MAX(messages.id) 

Ama bu çalışmıyor

DÜZENLEME: kullanmayı bir kez denedim :

LEFT JOIN messages 
    ON conversations.id = messages.convId 
     AND messages.id = MAX(messages.id) 

Ama belirten bir hata var: grup işlevinin geçersiz kullanımı.

+0

:

Ayrıca daha standart bir yaklaşım kullanarak bunu yapabilirsiniz conversations.id ASC TARAFINDAN SİPARİŞ, DESC – Nanocom

+0

messages.id o ben bana yalnızca bir satır verecek – Kilise

+0

Hayır başına bir satır gibi Hayır, birden çok satır verecektir. Ama benim hatam, ORDER BY conversations.id ASC, messages.id DESC GROUP BY sohbetler.id – Nanocom

cevap

12

DÜZENLEME

Bu çalışacak!

SELECT conversations.*, m1.* 
FROM conversations 
LEFT JOIN messages m1 
    ON conversations.id = m1.cid 
     AND m1.id = (
      SELECT MAX(m2.id) 
      FROM messages m2 
      WHERE m2.cid = conversations.id 
     ) 
+0

yazmış olmalıyım aslında bu işe yaramaz, sadece 1 satır için sınırlar, konuşmalar başına bir satır istiyorum. messags.convId – Kilise

+1

'daki en yüksek kimlik Bu nedenle, her konuşma için yalnızca en son iletiyi almak istiyor musunuz? –

+0

evet tam olarak ne istediğimi – Kilise

2

Bir grupta maksimum değeri mi arıyorsunuz? MySQL'in bunu yapmanın gerçekten açık bir yolu yoktur (bir parça hile ile birçok yol).

Ancak, yalnızca iki grup arıyorsunuz. Bu nedenle, sadece her grupta sınırı için bakmak ve union all kullanarak birleştirebilirsiniz:

SELECT m.msg, m.`read`, c.userid, 
     c.contactid 
FROM conversations c inner join 
    ((select m.* 
     from messages m 
     where m.convid = 443 
     order by m.id desc 
     limit 1 
    ) union all 
     (select m.* 
     from messages m 
     where m.convid = 444 
     order by m.id desc 
     limit 1 
    ) 
    ) m 
    ON c.id = m.convId; 

Eğer messages(convid, id) ve conversations(id) üzerine dizin varsa

, o zaman bu oldukça hızlı olmalıdır. Sen kimliğe göre mesajlarınızı sipariş edebilirsiniz

SELECT m.msg, m.`read`, c.userid, 
     c.contactid 
FROM conversations c inner join 
    messages m 
    ON c.id = m.convId 
where c.convId in (443, 444) and 
     m.id = (select max(id) from messages m2 where m2.convId = c.convId) 
İlgili konular