简体   繁体   中英

Two group in the same Query Mysql

I have a table (services) where it has the ID of the person who performed it and the value of the service and the date of completion. I need to add the value of the services by date and ID on the same line. It's possible?

SELECT sum(value) as total, id_user, data FROM os GROUP by data

Expected:

图片

图片

Your query is invalid SQL. MySQL let's this slip and selects the sum of values per day and one of the day's users arbitrarily picked.

What you are asking for, which is show all users with all their totals in one row, cannot be done in SQL. In SQL queries, you always select before-known columns. As there can be one user, or two, or ten thousand for a day, we obviously don't know all the columns beforehand.

You would rather either select rows:

SELECT sum(value) as total, id_user, data 
FROM os 
GROUP by data, id_user
ORDER by data, id_user;

Or select concatenated strings, eg:

SELECT
  group_concat(concat(id_user, ': ', total) order by id_user separator ', ') as totals,
  data
FROM
(
  SELECT sum(value) as total, id_user, data 
  FROM os 
  GROUP by data, id_user
) sums
ORDER by data;

If we can assume that: (but it could be very well that I don't understand the question)

  • There are always only two user_IDs per data
  • The higher user_ID should always appear in the ID_User column with the lower userID...

Then the following should work:

  • Generate two data identical sets that we can join together (C, D below)
  • Within each dataset assign the same rownumber to an ordered sequence in this case we order by data and ID_User
  • Now join these data sets on the generated RN+1 and RN so that row 1 from set C ties to row 2 of Set D
  • Now limit set C to only contain odd rows, thus set D will only have even rows. Provided the assumptions are true and we only have 2 users per data, then we will get the desired results.

Working Demo on Rextester

SELECT D.ID_USER, D.Total as Total, C.ID_USER, C.Total as Total_1, c.data
FROM (SELECT A.*, @RN:=@RN+1 RN
      FROM  OS A
      CROSS JOIN (SELECT @RN:=0) X
      ORDER BY Data, ID_USER) C
INNER JOIN (SELECT B.*, @RN2:=@RN2+1 RN
      FROM  OS B
      CROSS JOIN (SELECT @RN2:=0) X
      ORDER BY Data, ID_USER) D
 on C.RN+1=D.RN
 and C.Data=D.Data
WHERE mod(C.RN,2)=1;

Giving us:

+----+---------+-------+---------+---------+---------------------+
|    | ID_USER | Total | ID_USER | Total_1 |        data         |
+----+---------+-------+---------+---------+---------------------+
|  1 |       9 |  4,00 |       5 |    3,25 | 19.02.2018 00:00:00 |
|  2 |       9 |  1,50 |       5 |    1,00 | 20.02.2018 00:00:00 |
|  3 |       9 |  1,00 |       5 |    0,25 | 21.02.2018 00:00:00 |
+----+---------+-------+---------+---------+---------------------+

Now if there can be multiple users for a given data; I would need to understand your desired results in such a circumstance. Do we always have pairs? So if there are 3 the ID_user and total should be blank on a 2nd row having the same data? (if so just change the inner join to a left join) Should there be 2 additional columns added per user one for ID_user and one for total? (if so we now have a dynamic cross tab query in mySQL which can be accomplished but requires much more coding.

Graphically illustrate such edge cases by adding additional sample data to your question and mock up expected results for such data. This could be done by editing the rextester example I've provided or enhancing your graphic illustrations.

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