web-dev-qa-db-fra.com

groupe par premier caractère

J'ai un problème avec une requête dans Oracle SQL.

J'ai une colonne first_name dans une table employees. Je souhaite regrouper mes enregistrements en fonction du premier caractère de first_name.

Par exemple, j'ai 26 enregistrements, un avec name = 'Alice', un avec name = 'Bob' et ainsi de suite dans l'alphabet pour le premier caractère de chaque nom. Après la requête, il devrait y avoir 26 groupes avec un employé chacun.

J'ai essayé ce qui suit, mais ça ne marche pas:

SELECT employee_id, (SUBSTR(first_name,1,1)) AS alpha FROM employees
GROUP BY alpha;

name_which_starts_from       employees  
A                            10  
B                            2  
C                            4  
D                            9  
E                            3  
G                            3  
H                            3  
I                            2  
J                            16  
K                            7  
L                            6  
M                            6  
N                            4  
O                            1  
P                            6  
R                            3  
S                            13  
T                            4  
V                            2  
W                            3  
29
sonu

Votre requête est erronée, car vous devez exécuter une fonction d'agrégation sur EMPLOYEE_ID si vous souhaitez que cela fonctionne.

Comme:

select substr(first_name,1,1) as alpha, count(employee_id)
  from employees
 group by substr(first_name,1,1)

Qu'est-ce que vous essayez d'accomplir exactement?

57
Pablo Santa Cruz

Vous aurez besoin de regrouper par tout ce qui n'est pas une fonction d'agrégat, vous ne pouvez donc pas avoir employee_id dans la projection SELECT. Vous devez également grouper uniquement le premier caractère du prénom. Quelque chose comme ça devrait marcher:

SELECT  SUBSTR(first_name, 1, 1) AS alpha, COUNT(*) AS employee_count
FROM    employees
GROUP   BY SUBSTR(first_name, 1, 1);

Cela regrouperait la première lettre du prénom et indiquerait le nombre d'employés appartenant à ce groupe.

8
yukondude

Il semble presque que vous souhaitiez que 26 enregistrements soient renvoyés avec A, B, C dans la première colonne, puis une seconde colonne contenant tous les identifiants d'employé dans une liste délimitée. Si tel est le cas, voir la question 468990 et/ou ce lien Ask Tom . Quelque chose comme (non testé)

SELECT SUBSTR(first_name,1,1), TO_STRING( CAST( COLLECT( employee_id ) AS ntt_varchar2 ) ) AS empIDs
FROM   employees
GROUP  BY
SUBSTR(first_name,1,1);
2
Alistair Knock

Lorsque vous regroupez, toutes les colonnes de votre liste de sélection qui ne sont pas agrégées doivent également apparaître dans la clause "group by" (non pas avec employee_id).

Pourriez-vous préciser ce que vous essayez de faire?

1
Joe Suarez

Dans Rails/postgres, cela pourrait ressembler à ceci

group_clause = 'UPPER(LEFT(name, 1))'
Division.group(group_clause).order(group_clause).pluck(group_clause, 'COUNT(id)')
0
Paul Odeon

Je pense que je sais ce que vous essayez de faire ...

Vous devriez créer une petite table de référence avec une colonne 'lettre' (letter, sort_order)

Vous devriez votre requête en tant que

sélectionnez l.letter, comptez (e.id) en tant qu'employés de la lettre 1 quitté joint externe employé e sur l.letter = substr (e.first_name, 1,1)

l'autre réponse affichée vous donnera des résultats inattendus quand aucun employé ne porte une lettre spécifique à son nom ...

0
mson