46

I have a problem with a query in Oracle SQL.

I have a first_name column in an employees table. I want to group my records according to the first character in first_name.

For example, I have 26 records, one with name = 'Alice', one with name = 'Bob', and so on down the alphabet for each name's first character. After the query, there should be 26 groups with one employee each.

I tried the following, but it's not working:

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  
dreftymac
  • 31,404
  • 26
  • 119
  • 182
  • 1
    See the following link to a similar question for SQL Server: http://stackoverflow.com/questions/13500638/sql-how-many-records-start-with-the-same-letter – Robert Bernstein Nov 13 '13 at 20:17

7 Answers7

78

Your query is wrong, since you would need to perform some aggregation function on EMPLOYEE_ID if you want that to work.

Like:

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

What exactly you are trying to accomplish?

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
13

You'll need to group by everything that is not an aggregate function, so you can't have employee_id in the SELECT projection. You also need to group by just the first character of the first_name. Something like this should work:

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

That would group by the first letter of the first name, and show the number of employees that fall into that group.

yukondude
  • 24,013
  • 13
  • 49
  • 58
8

I have similar issue and solved it this with statement:

select SUBSTR(word, 1, 1) as S, count(word) FROM table_words group by S order by S ASC

output

I'm Geeker
  • 4,601
  • 5
  • 22
  • 41
prateeksharma
  • 81
  • 1
  • 1
2

It almost sounds like you want 26 records returned with A, B, C as the first column and then a second column containing all the employee IDs in a delimited list. If so see question 468990 and/or this Ask Tom link. Something like (untested)

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);
Alistair Knock
  • 1,806
  • 2
  • 16
  • 25
1

In Rails/postgres that might look something like this

group_clause = 'UPPER(LEFT(name, 1))'
Division.group(group_clause).order(group_clause).pluck(group_clause, 'COUNT(id)')
Paul Odeon
  • 4,407
  • 1
  • 37
  • 37
1

When you are grouping, all of the columns that appear in your select list that are not aggregated have to also appear in the "group by" clause (employee_id does not).

Could you clarify what it is you are trying to do?

Joe Suarez
  • 553
  • 1
  • 7
  • 21
0

I think i know what you are trying to do...

You should create a small reference table with a column 'letter' (letter, sort_order)

You should your query as

select l.letter, count(e.id) as employees from letter l left outer join employee e on l.letter = substr(e.first_name, 1,1)

the other answer posted will give you unexpected results when there are no employees with a specific letter in their name...

mson
  • 7,762
  • 6
  • 40
  • 70