简体   繁体   中英

how to get multiple 'group by' outputs as columns in one query in MySQL

I have a table with 3 columns

table data and structure:

id|username|work_type|points

----------

1|user 1  |walking  |1500
2|user 1  |running  |1500
3|user 2  |walking  |2500
4|user 3  |running  |1500
5|user 4  |walking  |1500
6|user 4  |walking  |1200

I need this output:

username|walking|running|points
user 1  |      1|      1|3000
user 2  |      1|      0|2500
user 3  |      0|      1|1500
user 4  |      2|      0|2700

what I have done:

Select * FROM (
Select Count(id),username as "username" from table where work_type='walking' group by username)
 USERNAME LEFT JOIN
Select Count(id),username as "walking" from table where work_type='walking' group by username)
 WALKING ON USERNAME.username=WALKING.username LEFT JOIN
Select Count(id),username as "running" from table where work_type='running' group by username)
 RUNNING ON USERNAME.username=RUNNING.username LEFT JOIN
Select SUM(points),username as "point" from table group by username)
 POINTS ON USERNAME.username=POINTS.username)

the above query gives the correct output, but since it takes 4 rounds in the same table it takes more time. this is only a logical structure of my actual DB table but it's similar. where it takes 1.4-2.1 Seconds since there are over 50k rows in the lowest one. I need to run the same query for 17 tables like this in one go. my time limit is about 20 seconds with about 2M+ rows. currently, it takes over 1 minute.

I don't think my SQL query is efficient. is there some way I can speed this up?. this is a DB that has been running for 3 years+ for commercial uses, so I cannot change the structures. these tables also need a left join from another table as well, but that I can build a different system for that if needed.

This kind of question is asked rather often. Generally, I think it's best resolved in application code, but anyway...

SELECT username
     , SUM(work_type = 'running') running
     , SUM(work_type = 'walking') walking
     , SUM(points) total 
  FROM my_table GROUP BY username;

The 'application code' version might look something like this:

SELECT username
     , work_type
     , COUNT(*) cnt 
     , SUM(points) total 
  FROM my_table 
GROUP 
    BY username
     , work_type;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM