Get data from two tables to make an event-calendar

2019-06-14 01:11发布

问题:

I have two tables

Table Users:

user_id     Name
1          John
2          Alice
3          Tom
4          Charles

Table Events:

id         event_id         start_date      end_date        user_id
1            1              2013-03-02      2013-03-03        1
2            2              2013-03-02      2013-03-03        3
3            3              2013-03-04      2013-03-04        1
4            2              2013-03-10      2013-03-15        2

I already made the "input" part and is not possible to have two events for the same user in the same day (no overlapping).

I provide the month and the year as variables.

I would like to have a mysql query with results like this:

user_id  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15       
  1      0  1  1  3  0  0  0  0  0  0   0   0   0   0   0
  2      0  0  0  0  0  0  0  0  0  2   2   2   2   2   2
  3      0  2  2  0  0  0  0  0  0  0   0   0   0   0   0

Thank you!

回答1:

UPDATED

SELECT user_id,
       COALESCE(MIN(CASE WHEN  1 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `1`,
       COALESCE(MIN(CASE WHEN  2 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `2`,
       COALESCE(MIN(CASE WHEN  3 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `3`,
       COALESCE(MIN(CASE WHEN  4 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `4`,
       COALESCE(MIN(CASE WHEN  5 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `5`,
       COALESCE(MIN(CASE WHEN  6 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `6`,
       COALESCE(MIN(CASE WHEN  7 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `7`,
       COALESCE(MIN(CASE WHEN  8 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `8`,
       COALESCE(MIN(CASE WHEN  9 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `9`,
       COALESCE(MIN(CASE WHEN 10 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `10`,
       COALESCE(MIN(CASE WHEN 11 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `11`,
       COALESCE(MIN(CASE WHEN 12 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `12`,
       COALESCE(MIN(CASE WHEN 13 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `13`,
       COALESCE(MIN(CASE WHEN 14 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `14`,
       COALESCE(MIN(CASE WHEN 15 BETWEEN DAY(start_date) AND DAY(end_date) THEN event_id END), 0) `15`
  FROM 
(
  SELECT id, event_id,
         CASE WHEN start_date < '2013-03-01' THEN '2013-03-01' ELSE start_date END start_date,
         CASE WHEN end_date   > '2013-03-31' THEN '2013-03-31' ELSE   end_date END end_date,
         user_id
    FROM events
   WHERE (start_date >= '2013-03-01' AND end_date <= '2013-03-31')
      OR (start_date <  '2013-03-01' AND end_date  > '2013-03-31')
      OR (start_date  < '2013-03-01' AND end_date BETWEEN '2013-03-01' AND '2013-03-31')
      OR (start_date BETWEEN '2013-03-01' AND '2013-03-31' AND end_date > '2013-03-31') 
) q
 GROUP BY user_id

Output:

| USER_ID | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
-----------------------------------------------------------------------------
|       1 | 0 | 1 | 1 | 3 | 0 | 0 | 0 | 0 | 0 |  0 |  0 |  0 |  0 |  0 |  0 |
|       2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  2 |  2 |  2 |  2 |  2 |  2 |
|       3 | 0 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 0 |  0 |  0 |  0 |  0 |  0 |  0 |

Here is SQLFiddle demo



回答2:

I tryed this:

SELECT user_id,
   COALESCE(MIN(CASE WHEN '2013-03-01' BETWEEN start_date AND end_date THEN event_id END), 0) `1`,
   COALESCE(MIN(CASE WHEN '2013-03-02' BETWEEN start_date AND end_date THEN event_id END), 0) `2`,
   COALESCE(MIN(CASE WHEN '2013-03-03' BETWEEN start_date AND end_date THEN event_id END), 0) `3`,
   COALESCE(MIN(CASE WHEN '2013-03-04' BETWEEN start_date AND end_date THEN event_id END), 0) `4`,
   COALESCE(MIN(CASE WHEN '2013-03-05' BETWEEN start_date AND end_date THEN event_id END), 0) `5`,
   COALESCE(MIN(CASE WHEN '2013-03-06' BETWEEN start_date AND end_date THEN event_id END), 0) `6`,
   COALESCE(MIN(CASE WHEN '2013-03-07' BETWEEN start_date AND end_date THEN event_id END), 0) `7`,
   COALESCE(MIN(CASE WHEN '2013-03-08' BETWEEN start_date AND end_date THEN event_id END), 0) `8`,
   COALESCE(MIN(CASE WHEN '2013-03-09' BETWEEN start_date AND end_date THEN event_id END), 0) `9`,
   COALESCE(MIN(CASE WHEN '2013-03-10' BETWEEN start_date AND end_date THEN event_id END), 0) `10`,
   COALESCE(MIN(CASE WHEN '2013-03-11' BETWEEN start_date AND end_date THEN event_id END), 0) `11`,
   COALESCE(MIN(CASE WHEN '2013-03-12' BETWEEN start_date AND end_date THEN event_id END), 0) `12`,
   COALESCE(MIN(CASE WHEN '2013-03-13' BETWEEN start_date AND end_date THEN event_id END), 0) `13`,
   COALESCE(MIN(CASE WHEN '2013-03-14' BETWEEN start_date AND end_date THEN event_id END), 0) `14`,
   COALESCE(MIN(CASE WHEN '2013-03-15' BETWEEN start_date AND end_date THEN event_id END), 0) `15`
FROM events 
GROUP BY user_id