2013-09-16 13 views
7

To mój pełny zapytania:MySQL GROUP BY i ORDER BY DESC

SELECT * FROM `clientgroupassign` 
LEFT JOIN `clients` ON `clientgroupassign`.clientId = `clients`.clientId 
LEFT JOIN `users` ON `carerId` = `userId` 
LEFT JOIN 
    (SELECT * FROM 
     (SELECT * FROM `contacts` WHERE `contactGroup` = 4 ORDER BY `contactId` DESC) 
     as `contacts` 
    GROUP BY (`contactClientId`) 
    ) AS `contacts` ON `contactClientId` = `clients`.clientId 
WHERE groupId = 4 
ORDER BY `clients`.clientId 

Jest problem z trzecim dołączyć skrypt powoduje wykonanie przez około 1 minutę. Po uruchomieniu go w PMA:

SELECT * FROM (SELECT * FROM `contacts` WHERE `contactGroup` = 4 ORDER BY `contactId` DESC) AS `contacts` GROUP BY (`contactClientId`) 

nadal trwa bardzo długo.

Chcę uzyskać jeden, ostatni dodany wiersz od contacts dla każdego klienta, który jest w grupie 4 (klient może być w różnych grupach).

Dzięki.

+1

Co 'DESCRIBE' /' pokaż EXPLAIN' dla tej kwerendy? – BlitZ

+2

Usuń również "SELECT * ...". Wybierz określone kolumny. Może dodać dodatkowe obciążenie. "SELECT *" może być prawdziwym zabójcą prędkości. – BlitZ

Odpowiedz

6

Aby dostać „ostatni dodany wiersz z kontaktów dla każdego klienta, który jest w grupie 4” spróbuj tego:

SELECT 
    c.* 
FROM(
    SELECT 
     contactClientId, 
     MAX(contactId) as cid 
    FROM 
     contacts 
    WHERE 
     contactGroup = 4 
    GROUP BY 
     contactClientId 
    ORDER BY 
     NULL 
) as tmp 
INNER JOIN contacts as c 
    ON c.contactId = tmp.cid 
    AND c.contactClientId = tmp.contactClientId 

Jeśli contactId jest PK w contacts następnie dołączyć klauzulę sekund nie jest potrzebne.

Domyślnie MySQL sortuje wszystkie GROUP BY col1, col2 ... zapytania jakbyś określono ORDER BY col1, col2 ... w zapytaniu także. Jeśli użytkownik posiada klauzulę ORDER BY, która zawiera tę samą kolumnę, to MySQL optymalizuje ją bez żadnych ograniczeń szybkości, chociaż sortowanie nadal występuje. Jeśli zapytanie obejmuje GROUP BY, ale chcesz, aby uniknąć kosztu posortowania wyniku, możesz wyłączyć sortowanie według , podając ORDER BY NULL.

Kompletna docs.

Pełna zapytania:

SELECT * FROM `clientgroupassign` 
LEFT JOIN `clients` ON `clientgroupassign`.clientId = `clients`.clientId 
LEFT JOIN `users` ON `carerId` = `userId` 
LEFT JOIN 
    (
     SELECT 
      c.* 
     FROM(
      SELECT 
       contactClientId, 
       MAX(contactId) as cid 
      FROM 
       contacts 
      WHERE 
       contactGroup = 4 
      GROUP BY 
       contactClientId 
      ORDER BY 
       NULL 
     ) as tmp 
     INNER JOIN contacts as c 
      ON c.contactId = tmp.cid 
      AND c.contactClientId = tmp.contactClientId 
    ) AS `contacts` ON `contactClientId` = `clients`.clientId 
WHERE groupId = 4 
ORDER BY `clients`.clientId 
+1

Jaki jest sens "ZAMÓWIENIA PRZEZ NULL"? – GarethD

+1

@GarethD jego optymalizacja, zasadniczo filesort nie będzie używany podczas grupowania danych – Stephan

+1

@CORRUPT przepraszam za literówkę, naprawiony teraz, thx – Stephan