SQL Column / Row Grouping
I am new to SQL. I am looking for a simple SQL solution to concatenate a row / column for a row whose column contains the same data, in this case the zip code. For example, viewing the data looks like this:
state, county, city, zip, count "CA", "ALAMEDA", "HAYWARD", "94541", 5371 "CA", "ALAMEDA", "HAYWARD", "94542", 2209 "CA", "ALAMEDA", "HAYWARD", "94544", 7179 "CA", "ALAMEDA", "HAYWARD", "94545", 4209 "CA", "ALAMEDA", "CASTRO VALLEY", "94546", 7213 "CA", "ALAMEDA", "HAYWARD", "94546", 37 "CA", "ALAMEDA", "LIVERMORE", "94550", 9809 "CA", "ALAMEDA", "LIVERMORE", "94551", 6558 "CA", "ALAMEDA", "CASTRO VALLEY", "94552", 3121 "CA", "ALAMEDA", "HAYWARD", "94552", 12 "CA", "ALAMEDA", "FREMONT", "94555", 5392
I would like to get the data so that it looks like this:
state, county, city, zip, count "CA", "ALAMEDA", "HAYWARD", "94541", 5371 "CA", "ALAMEDA", "HAYWARD", "94542", 2209 "CA", "ALAMEDA", "HAYWARD", "94544", 7179 "CA", "ALAMEDA", "HAYWARD", "94545", 4209 "CA", "ALAMEDA", "CASTRO VALLEY / HAYWARD", "94546", 7250 "CA", "ALAMEDA", "LIVERMORE", "94550", 9809 "CA", "ALAMEDA", "LIVERMORE", "94551", 6558 "CA", "ALAMEDA", "CASTRO VALLEY HAYWARD", "94552", 3133 "CA", "ALAMEDA", "FREMONT", "94555", 5392
You can see that the data has been combined or summed in the two rows. For rows containing the same postal code, the city names (both) appear in the city column, and count is the sum of the count from each row.
Is there a way to do this using SQL? Even if it requires two different SQL statements.
source to share
Assuming SQL Server you can use FOR XML
to get the results you want .
select distinct t.state,t.county,t.zip,t2.sumcount,
STUFF(
(
SELECT '/' + city AS [text()]
FROM mytable t3
WHERE t.zip = t3.zip
FOR XML PATH('')
), 1, 1, '') AS ColList
from mytable t
join (select zip, sum(count) as sumcount
from mytable
group by zip) t2 on t.zip=t2.zip
And some SQL Fiddle .
If you are using MySQL take a look at GROUP_CONCAT
:
select distinct t.state,t.county,t.zip,t2.sumcount,
GROUP_CONCAT(t.city) as cities
from mytable t
join (select zip, sum(count) as sumcount
from mytable
group by zip) t2 on t.zip=t2.zip
GROUP BY t.state,t.county,t.zip,t2.sumcount
And also Fiddle .
Good luck.
source to share
I improved on sgeddes' excellent answer to actually get the counter and avoid duplicate entries, and added script support so you can test it. This assumes SQL Server.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'MYTABLE') BEGIN
drop table MYTABLE;
END;
go
create table MYTABLE
(
state nvarchar(2)
,county nvarchar(100)
,city nvarchar(100)
,zip nvarchar(10)
)
go
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94541');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94541');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94544');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94545');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94546');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','LIVERMORE','94550');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','LIVERMORE','94551');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','CASTRO VALLEY','94552');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','HAYWARD','94552');
insert into MYTABLE(state,county,city,zip) values('CA','ALAMEDA','FREMONT','94555');
select distinct
t.state
,t.county
,t.zip
,t2.sumcount
,STUFF((
SELECT distinct '/' + city AS [text()]
FROM mytable t3
WHERE t.zip = t3.zip
FOR XML PATH('')
), 1, 1, '') AS ColList
from
mytable t
inner join
(
select zip, sum(count) as sumcount
from
(
select zip,count(*) as count
from mytable
group by zip
) x
group by zip
) t2
on t.zip=t2.zip
The result looks like this:
state county zip sumcount ColList
CA ALAMEDA 94541 2 HAYWARD
CA ALAMEDA 94544 1 HAYWARD
CA ALAMEDA 94545 1 HAYWARD
CA ALAMEDA 94546 9 CASTRO VALLEY/HAYWARD
CA ALAMEDA 94550 1 LIVERMORE
CA ALAMEDA 94551 1 LIVERMORE
CA ALAMEDA 94552 2 CASTRO VALLEY/HAYWARD
CA ALAMEDA 94555 1 FREMONT
source to share