1
votes

Comment faire un groupe sur des lignes spécifiques

J'exécute la requête suivante pour récupérer les données:

 student_id |              student_name
------------+----------------------------------------
  41990     | James
  48220     | John
  00000     | Name-doesnt-exist

Les données que je récupère ressemblent à ceci:

 student_id |              student_name
------------+----------------------------------------
  41990     | James
  48220     | John
  00000     |
  00000     | lkjkj
  00000     | random name
  00000     | somethingelse

I aimerait plutôt récupérer ces données:

SELECT DISTINCT student_id, student_name from class_students where city = 'foobar' and student_id <> 0;

Ce qui signifie regrouper tous les 00000 en une seule ligne avec le nom NA


1 commentaires

Peut-être que vous vouliez vraiment simplement <> '00000' ?


3 Réponses :


0
votes

Vous pouvez essayer d'utiliser row_number()

select student_id,coalesce(student_name,'Name-doesnt-exist') as name
from
(
SELECT student_id, student_name,row_number() over(partition by student_id order by case when student_name is null then 1 else 2 end) as rn
from class_students where city = 'foobar' and student_id <> 0
)A where rn=1


0 commentaires

1
votes
SELECT student_id, case when student_id = '00000' then 'N-A' else max(student_name) end
from class_students 
where city = 'foobar' 
  and student_id <> 0
group by student_id

3 commentaires

Merci cela fonctionne. Pouvez-vous expliquer ce que fait max ici dans la clause else? Aussi généralement quand j'essaye de grouper par, je me plains que group by doit avoir les mêmes colonnes que select, mais cela ne semble pas être le cas ici.


@Anthony, c'est essentiellement une agrégation factice car cette fonction fonctionne sur plusieurs lignes de données. Je pense que vous trouverez que ma réponse est l'approche générale dont vous avez besoin.


@Anthony: Lorsque vous groupez par colonne, vous ne pouvez pas simplement sélectionner ce que vous voulez. Vous pouvez sélectionner toutes les colonnes que vous regroupez. Toutes les autres colonnes que vous souhaitez sélectionner doivent être agrégées, ce qui signifie qu'elles doivent être combinées de quelque manière que ce soit. J'utilise max () pour obtenir le nom d'élève le plus élevé pour chaque groupe. Dans votre cas, il n'y a qu'un seul nom pour chaque groupe et plusieurs une seule fois pour «00000». Si vous comprenez vraiment ce que signifie le regroupement, vous comprenez pourquoi vous ne pouvez pas simplement tout sélectionner.



1
votes

S'il existe plus d'un nom, marquez-le.

having count(distinct student_name) = 1

Vous pouvez également éliminer complètement ces groupes des résultats:

select student_id,
    case when count(distinct student_name) > 1 then 'N/A' else min(student_name) end as student_name
from class_students
where city = 'foobar' and student_id <> 0
group by student_id

p >


0 commentaires