sql >> Databasteknik >  >> RDS >> Mysql

MySQL LEFT JOIN med MAX &GROUP BY på sammanfogat bord?

Det "senaste per grupp"-problemet är extremt vanligt i SQL. Det finns otaliga exempel på lösningar på just detta problem bara på den här webbplatsen.

Om dina tidsstämplar är unika per medlemsaktivitet:

SELECT
  m.id,
  m.name,
  a.code activity_code,
  a.timestamp activity_timestamp,
  a.description activity_description
FROM
  members m
  INNER JOIN activities a ON a.member_id = m.id
WHERE
  a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)

alternativt, om ditt aktivitets-ID ökar monotont med tiden:

  ...
WHERE
  a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)

Du behöver inte gruppera. Men frågan kommer att dra nytta av ett index över activities över (member_id, timestamp) eller (member_id, id) , respektive.

REDIGERA

För att visa medlemmar som inte har loggat en aktivitet, använd en vänsteranslutning så här.

SELECT
  m.id,
  m.name,
  a.code activity_code,
  a.timestamp activity_timestamp,
  a.description activity_description
FROM
  members m
  LEFT JOIN activities a ON 
    a.member_id = m.id
    AND a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)

Observera att det inte finns någon WHERE klausul. Semantiskt tillämpas WHERE efter sammanfogningarna är gjorda. Så en WHERE-sats skulle ta bort raderna som LEFT JOIN lade till, vilket i praktiken ger samma resultat som den ursprungliga INNER JOIN.

Men om du använder det extra predikatet höger i anslutningsvillkoret kommer LEFT JOIN att fungera som förväntat.



  1. Assembly 'Microsoft.SqlServer.Types' version 10 eller högre kunde inte hittas

  2. Alternativ till utom i MySQL

  3. Välja distinkt 2 kolumnkombination i mysql

  4. Det går inte att ansluta PostgreSQL till fjärrdatabas med pgAdmin