Как использовать GROUP BY для результата с ОГРАНИЧЕНИЕМ и СМЕЩЕНИЕМ?

#mysql #group-by #limit #offset

#mysql #группировка по #ограничение #смещение

Вопрос:

Я использую MySQL 5.6, и у меня проблема с результатами запроса с использованием GROUP BY и LIMIT OFFEST . Эти результаты не согласуются с результатами без OFFSET . Почему? И каково решение?

Этот запрос (no OFFSET и no GROUP BY ) дал мне 10 результатов:

 SELECT sp.couleur, sp.nom, d.degre_urgence 
FROM demande_interservices AS d 
LEFT JOIN demande_interservices_a_valider AS dv ON d.id = dv.demande_interservices_id  
LEFT JOIN demande_interservices_affectee_a_sous_pole AS d_aff ON d.id = d_aff.demande_interservices_id 
LEFT JOIN sous_pole AS sp ON d_aff.sous_pole_id = sp.id 
WHERE d.pole_sollicite_id = (SELECT pole_id FROM utilisateur WHERE id = 38) 
AND (d.statut_id = 1 OR d.statut_id = 2) 
AND dv.demande_interservices_id IS NULL 
ORDER BY d.degre_urgence DESC 
LIMIT 10
  

Результаты:

 couleur    degre_urgence    nom
_______________________________

#cd423a    5    Communication
#cd423a    5    Communication
#ff3ebb    5    Assistante DGS
#925210    5    Police Urbanisme
#000000    5    informatique RGPD
#cd423a    5    Communication
#ff3ebb    5    Assistante DGS
#e2c63d    5    Urbanisme - Marchés Publics
#ff3ebb    5    Assistante DGS
#925210    4    Police Urbanisme
  

Тот же запрос с GROUP BY ;

 SELECT sp.couleur, sp.nom, d.degre_urgence 
FROM demande_interservices AS d 
LEFT JOIN demande_interservices_a_valider AS dv ON d.id = dv.demande_interservices_id 
LEFT JOIN demande_interservices_affectee_a_sous_pole AS d_aff ON d.id = d_aff.demande_interservices_id 
LEFT JOIN sous_pole AS sp ON d_aff.sous_pole_id = sp.id 
WHERE d.pole_sollicite_id = (SELECT pole_id FROM utilisateur WHERE id = 38) 
AND (d.statut_id = 1 OR d.statut_id = 2) 
AND dv.demande_interservices_id IS NULL 
GROUP BY nom
ORDER BY d.degre_urgence DESC 
LIMIT 10
  

Результаты:

 couleur    degre_urgence    nom
_______________________________

#e2c63d    5    Urbanisme - Marchés Publics
#000000    5    informatique RGPD
#925210    5    Police Urbanisme
#fff000    2    Accueil    
#7bd026    1    ASVP
#cd423a    1    Communication
#ff3ebb    1    Assistante DGS
  

Но я ожидал этих результатов:

 couleur    degre_urgence    nom
_______________________________

#cd423a    5    Communication
#ff3ebb    5    Assistante DGS
#925210    5    Police Urbanisme
#000000    5    informatique RGPD
#e2c63d    5    Urbanisme - Marchés Publics
  

Комментарии:

1. Является d.degre_urgence числовым? Не могли бы вы добавить эти значения в приведенные выше таблицы примеров, чтобы понять ORDER BY .

2. Да, это целое число, от 1 до 5. Я отредактировал результаты.

Ответ №1:

Вы должны сгруппировать результат вашего первого запроса:

 select t.nom, min(t.couleur) from (
  SELECT sp.couleur, sp.nom 
  FROM demande_interservices AS d 
  LEFT JOIN demande_interservices_a_valider AS dv ON d.id = dv.demande_interservices_id 
  LEFT JOIN demande_interservices_affectee_a_sous_pole AS d_aff ON d.id = 
  d_aff.demande_interservices_id 
  LEFT JOIN sous_pole AS sp ON d_aff.sous_pole_id = sp.id 
  WHERE d.pole_sollicite_id = (SELECT pole_id FROM utilisateur WHERE id = 38) 
  AND (d.statut_id = 1 OR d.statut_id = 2) 
  AND dv.demande_interservices_id IS NULL 
  ORDER BY d.degre_urgence DESC 
  LIMIT 10
) t
GROUP BY t.nom
  

MySQL позволяет использовать couleur вместо min (couleur), хотя это не стандарт sql.

Комментарии:

1. Это на самом деле (новый) стандарт, если couleur он функционально зависит от nom .

2. О, я вижу, я должен сделать это в 2 шага, чтобы сгруппировать по тому же результату. Это отлично работает, спасибо вам!! Если кто-нибудь может объяснить причину, по которой GROUP BY with LIMIT влияет на результаты, это было бы здорово, мне нравится понимать вещи 🙂

3. Вы хотите получить результаты следующим образом: сначала выполните подзапрос, затем ограничьте его результаты только 10 строками, а затем используйте группировку для этих ограниченных результатов. Это то, что я понял из ваших ожидаемых результатов.

4. Действительно, это для разбивки на страницы, только 10 строк для отображения на каждой странице. И группировка предназначена для заголовка, который должен соответствовать 10 показанным строкам.

Ответ №2:

Вы могли бы использовать min() и group by

 SELECT min(sp.couleur), sp.nom 
FROM demande_interservices AS d 
LEFT JOIN demande_interservices_a_valider AS dv ON d.id = dv.demande_interservices_id  
  AND dv.demande_interservices_id IS NULL 
LEFT JOIN demande_interservices_affectee_a_sous_pole AS d_aff ON d.id = d_aff.demande_interservices_id 
LEFT JOIN sous_pole AS sp ON d_aff.sous_pole_id = sp.id 
WHERE d.pole_sollicite_id = ( SELECT pole_id FROM utilisateur WHERE id = 38) 
AND (d.statut_id = 1 OR d.statut_id = 2) 
GROUP BY sp.nom 
LIMIT 10 
  

Комментарии:

1. Я получаю тот же результат :/

2. ответ обновлен .. для неправильного левого соединения.. в любом случае, для ваших данных невозможно получить один и тот же результат для group by и not .. убедитесь, что у вас есть min (sp.couleur) в select

3. Снова тот же результат. Почему это min() изменило бы результат?

4. ВЫБЕРИТЕ min (sp.couleur), sp.nom ..и group by должна повторно указать количество возвращаемых строк