SQL-запрос, чтобы получить пользователей, которые имеют события в своем календаре - PullRequest
0 голосов
/ 31 октября 2018

У меня есть следующие таблицы базы данных:

Таблица пользователей:

| id  |  name |
| 1   |  bob  |
| 2   |  jane |
| 3   |  tim  |
| 4   |  rex  |

Таблица событий:

| id  | user_id | date       |
| 1   |    1    | 12/05/2018 |
| 2   |    1    | 13/05/2018 |
| 2   |    2    | 15/05/2018 |
| 3   |    2    | 16/05/2018 |
| 4   |    3    | 27/05/2018 |

Я хотел бы создать запрос SQL, который извлекает всех пользователей, у которых есть какие-либо события в течение ближайших 7 дней, а также возвращает столбец для каждого из 7 дней со счетчиком количества событий, которые пользователь забронировал для каждого из в те дни.

В идеале это то, чего я хотел бы достичь:

| user_id | 12/05/2018 | 13/11/2018 | 14/11/2018 | 15/11/2018 |
| 1       | 1          | 1          | 0          | 0          |
| 2       | 0          | 0          | 0          | 1          |

Пока у меня есть это ниже как отправная точка, но это не работает, так как возвращает ноль строк:

SELECT
    users.id,
    name
FROM
    `users`
    inner join bookings on `users`.`id` = bookings.teacher_id
WHERE
    bookings.`date` BETWEEN NOW() AND DATE_ADD( NOW(), INTERVAL 7 DAY )

Может кто-нибудь помочь мне сделать это? Возможно ли это даже в 1 запросе SQL?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Очень трудно генерировать имена столбцов в виде строк следующих дат (например, «2018-11-01», «2018-11-02») без жесткого кодирования.

Но я мог бы прийти с ответом, какие имена столбцов названы d1..d7. Надеюсь, это хорошо в вашем случае. Возможно, это не оптимальное решение, но оно работает.

SELECT
  tt.user_id,
  SUM(tt.d1) AS d1,
  SUM(tt.d2) AS d2,
  SUM(tt.d3) AS d3,
  SUM(tt.d4) AS d4,
  SUM(tt.d5) AS d5,
  SUM(tt.d6) AS d6,
  SUM(tt.d7) AS d7
FROM
  (SELECT
   t.user_id,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 1 DAY)) THEN t.total ELSE 0 
END) AS d1,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 2 DAY)) THEN t.total ELSE 0 
END) AS d2,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 3 DAY)) THEN t.total ELSE 0 
END) AS d3,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 4 DAY)) THEN t.total ELSE 0 
END) AS d4,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 5 DAY)) THEN t.total ELSE 0 
END) AS d5,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 6 DAY)) THEN t.total ELSE 0 
END) AS d6,
   (CASE WHEN t.`date` = DATE(DATE_ADD(NOW(), INTERVAL 7 DAY)) THEN t.total ELSE 0 
END) AS d7

  FROM
  (
    SELECT b.user_id, b.`date`, COUNT(*) as total 
    FROM `bookings` b
    WHERE b.`date` BETWEEN NOW() AND DATE_ADD( NOW(), INTERVAL 7 DAY )
    GROUP BY b.user_id, b.`date`) t
  ) tt

 GROUP BY tt.user_id

Этот запрос дает мне такой результат для таблицы, как вы дали.

| user_id | d1 | d2 | d3 | d4 | d5 | d6 | d7 |
----------------------------------------------
|    1    | 1  | 0  | 0  | 0  | 0  | 0  | 0  |
|    2    | 0  | 1  | 1  | 0  | 0  | 0  | 0  |
|    3    | 0  | 0  | 0  | 0  | 1  | 0  | 0  |

Здесь d1 означает следующий день. d2 означает послезавтра и т. Д.

Также это решение также дает столбец со всеми нулями (то есть дни без каких-либо событий)

0 голосов
/ 31 октября 2018

На самом деле здесь вам нужно присоединиться
Это потому, что вы хотите, чтобы элементы из таблицы 'user' не имели ссылок в бронировании таблицы.
Использование LEFT JOIN вернет все элементы в таблице пользователя, независимо от того, имеет ли он бронирование или нет, затем с помощью условия WHERE вы фильтруете и сохраняете только тех, у кого нет бронирования (booking.id IS NULL)

SELECT
    u.id AS userId,
    u.name AS userName
FROM
    `user` AS u
    LEFT JOIN booking AS b ON (
            u.id = b.userId
            AND b.`date` BETWEEN NOW() AND DATE_ADD( NOW(), INTERVAL 7 DAY )
        )
WHERE
    ISNULL(b.id)

в соглашении sql это иметь имя таблицы в единственном числе ... в nosql это другой способ, просто перепутать все ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...