Mysql
 sql >> база данни >  >> RDS >> Mysql

Избор на поръчка въз основа на резултатите от присъединяването (сортиране на разговори при последното изпратено съобщение)

Проблемът се дължи на специфично за MySQL разширение за поведението на GROUP BY клауза. Други бази данни биха извадили грешка... нещо подобно на on-agregate в списъка SELECT". (Можем да накараме MySQL да изведе подобна грешка, ако включим ONLY_FULL_GROUP_BY в sql_mode.)

Проблемът с израза messages.created е, че се отнася до стойност от неопределен ред в GROUP BY. Операцията ORDER BY се появява много по-късно при обработката, след операцията GROUP BY.

За да получите „най-новото“, създадено за всяка група, използвайте агрегат израз MAX(messages.created) .

За да получите другите стойности от същия ред, е малко по-сложно.

Ако приемем, че created е уникален в рамките на даден conversation_id група (или, ако няма гаранция, че не е уникална и сте добре да връщате няколко реда с една и съща стойност за created ...

За да получите най-новото created за всеки conversation_id

SELECT lm.conversation_id
     , MAX(lm.created) AS created
  FROM conversation lc
  JOIN message lm
    ON lm.conversation_id = lc.id
 WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
 GROUP BY lm.conversation_id

Можете да го използвате като вграден изглед, за да получите целия ред с този най-нов created

SELECT c.*
     , m.*
  FROM ( SELECT lm.conversation_id
              , MAX(lm.created) AS created
           FROM conversation lc
           JOIN message lm
             ON lm.conversation_id = lc.id
          WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
          GROUP BY lm.conversation_id
       ) l
  JOIN conversation c
    ON c.id = l.conversation_id
  JOIN messages m
    ON m.conversation_id = l.conversation_id
   AND m.created         = l.created
 WHERE (c.creator_id = :userId OR c.to_id = :userId)

БЕЛЕЖКИ:

Можете да добавите ORDER BY клауза, за да подредите връщането на редовете, колкото ви е необходимо.

WHERE клаузата във външната заявка вероятно е излишна и ненужна.

Предпочитаме да избягваме използването на SELECT * и предпочитат изрично да изброят изразите, които трябва да бъдат върнати.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Enum в Hibernate, запазващ се като enum

  2. Един към много MySQL

  3. Как да настроите часовата зона на базата данни в application.ini

  4. Помощ при SQL заявка за намиране на следващата свободна дата за система за резервации

  5. Entity Framework + генериране на клас MySQL