0
votes

SQL - trie avant le groupe par

J'ai un produit de table:


| id       | code     | active
--------------------------------
| 1        | 1111     | 0    |
| 4        | 2222     | 0    |
| 7        | 3333     | 0    |
--------------------------------

Et je veux choisir un enregistrement de chaque code. Mais si active = 1, alors l'enregistrement a la priorité. Donc je veux voir:


select * from (Select * from products order by active desc) as query group by code 

J'ai essayé:

| id       | code     | active
--------------------------------
| 3        | 1111     | 1    |
| 5        | 2222     | 1    |
| 7        | 3333     | 0    |
--------------------------------

Mais je ne fonctionne pas et montre :


| id       | code     | active
--------------------------------
| 1        | 1111     | 0    |
| 2        | 1111     | 0    |
| 3        | 1111     | 1    |
| 4        | 2222     | 0    |
| 5        | 2222     | 1    |
| 6        | 2222     | 0    |
| 7        | 3333     | 0    |
| 8        | 3333     | 0    |
| 9        | 3333     | 0    |
--------------------------------

Quelqu'un peut-il m'aider? Merci!


0 commentaires

3 Réponses :


0
votes

Utilisez une sous-requête corrélée:

select p.*
from products p
where p.id = (select p2.id 
              from products p2
              where p2.code = p.code
              order by p2.active desc
              limit 1
             );

GROUP BY sert à résumer les lignes, pas à sélectionner une ligne particulière.


2 commentaires

J'ai eu une erreur: "La sous-requête renvoie plus d'une ligne" @Gordon Linoff


@MaronFive. . . C'est corrigé maintenant.



4
votes

Avec l'agrégation conditionnelle:

> id | code | active
> -: | ---: | -----:
>  3 | 1111 |      1
>  5 | 2222 |      1
>  7 | 3333 |      0

Pour MySql 8.0+, vous pouvez utiliser ROW_NUMBER():

select p.id, p.code, p.active
from (
  select *, row_number() over (partition by code order by active desc, id) rn
  from products
) p 
where p.rn = 1  

Voir la démo .
Résultats:

select 
  coalesce(min(case when active = 1 then id end), min(id)) id, code, max(active) active
from products
group by code


1 commentaires

Woah, merci beaucoup! Toutes les réponses fonctionnent parfaitement!



1
votes

Vous pouvez utiliser la fonction row_number ici:

select x.*
from
(select a.*,
       row_number() Over(partition by code order by active desc) as rownum1
from products a) x
where x.rownum1=1

J'espère que cela vous aidera.


0 commentaires