Какие велосипеды были в прямом эфире 8 декабря? - PullRequest
2 голосов
/ 05 июня 2019

Я новичок в SQL (MySql), и я застрял с этой проблемой в одном из своих заданий и не смог получить ответ от кого-либо или поиска в Интернете по этому вопросу.Вопрос звучит так:

Какие велосипеды были живы (is_live = TRUE) 8 декабря?(Только отображение bike_id).
Примечание. В таблице нет записи строки на 8 декабря, и это соответствует назначению

Name        Type      Description
id          int       LOG ID(PK)
bike_id     int       id of the bike
is_live     boolean   flag to indicate whether bike is live (TRUE/FALSE)
updated_on  Date      Date on which status of bike was updated

Таблица BIKE_LIVE_LOG:

id  bike_id     is_live   updated_on  
1      1        TRUE      2018-12-01
2      2        TRUE      2018-12-01
3      3        TRUE      2018-12-01
4      3        FALSE     2018-12-02
5      2        FALSE     2018-12-05
6      3        TRUE      2018-12-10

Я не мог продвинуться вперед с вопросом, поскольку я даже не понимаю подход к нему с моими текущими знаниями.

Я использовал этот запрос, чтобы сгенерировать last_update_date, сгруппированный по каждому bike_id.

select bll.bike_id, max(bll.updated_on) as last_update_date
from bike_live_log as bll
where bll.updated_on <= '2018-12-08'
group by bll.bike_id; 

Выход будет 1.

Ответы [ 4 ]

3 голосов
/ 05 июня 2019

Я постараюсь помочь вам добраться до последнего шага.Вы действительно, очень близко!

Вы были правы, когда шли по пути поиска самой последней даты updated_on для каждого bike_id.Неважно, сколько раз велосипед был включен или выключен;вы действительно заботитесь только о самом последнем статусе до даты, которая вас интересует.

Имея текущий запрос, вы уже знаете, когда каждый bike_id последний раз обновлялся до 8 декабря.

Далее, вы можете использовать эту информацию, чтобы узнать, какое значение is_live было для каждого из этих bike_id значений на данный момент last_update_date.

Это можно сделать с помощьюсуществующий запрос в качестве подзапроса или CTE, если вы предпочитаете, и снова присоединитесь к основной таблице.Ваши JOIN критерии будут bike_id до bike_id и updated_on до last_update_date.Присоединяясь к датам, вы будете возвращать только одну запись для каждого bike_id, и эта запись будет той, которая вас интересует.

После того, как вы собрали свой JOIN, выВам просто нужно добавить предложение WHERE, чтобы ограничить ваш результирующий набор строками, где is_live = 'TRUE', что будет возвращать только bike_id из 1.

1 голос
/ 05 июня 2019

Ваше требование может быть выражено более ориентировано на данные: найти велосипеды, чей последний известный статус 8 декабря или ранее был жив .

Это один из способов (ИМХО самый читаемый), чтобы выразить это в SQL:

select bike_id
from bike_live_log bll
where updated_on = (
    select max(updated_on)
    from bike_live_log
    where bike_id = bll.bike_id
    and updated_on <= '2018-12-08'
)
and is_live

Подзапрос (corelated) находит дату последнего обновления 8 декабря или ранее для текущей строки внешнего запроса. Если такой строки нет, будет возвращено null, что не будет совпадать ни с одной строкой из внешнего запроса, поэтому будут возвращены только велосипеды с данными до или 8 декабря.

0 голосов
/ 11 июня 2019
SELECT
bike_id,
MAX(CASE WHEN last_live_date <= '2018-12-08' AND ( last_not_live_date < last_live_date OR last_not_live_date IS NULL) THEN 1 ELSE 0 END) AS final_status
FROM
(
SELECT
    bike_id,
    MAX(CASE WHEN is_live = TRUE THEN updated_on END) AS last_live_date,
    MAX(CASE WHEN is_live = FALSE THEN updated_on END) AS last_not_live_date
FROM `BIKE_LIVE_LOG`
WHERE updated_on <= '2018-12-08'
GROUP BY bike_id
) AS a
GROUP BY bike_id
HAVING final_status = 1;
0 голосов
/ 05 июня 2019

ТЛ; др

Вот код MySQL, который вам нужен:

SELECT bike_id FROM (
  SELECT * FROM (
    SELECT * FROM bikes 
    WHERE updated_on < '20181209'
    ORDER BY updated_on DESC, id DESC
  ) AS sub 
  GROUP BY bike_id
) AS sub2
WHERE is_live = true

Почему это работает?

Нам нужно немного разбить вопрос. Мне нравится начинать с позиции «как я могу получить нужную мне информацию в формате, который имеет смысл для меня (как человека)?».

Итак, первое, что я сделал, это получил список всех велосипедов с датами updated_on до 9-го декабря (т.е. были обновлены 8-го декабря или раньше). Я также заказал это по полю updated_on, чтобы я (как человек) мог легко увидеть «последнюю» запись, которая сообщит мне самый последний статус каждого велосипеда до или 8-го декабря:

SELECT * FROM bikes 
WHERE updated_on < '20181209'
ORDER BY updated_on DESC, id DESC

Из этого я вижу, что до 9-го декабря есть 5 записей об изменении статуса велосипеда. Я легко вижу, что для каждого велосипеда есть несколько записей «обновления», но теперь я могу начать с верхней части списка, и каждый идентификатор велосипеда, с которым я сталкиваюсь - это статус 8 декабря

Дополнительно я добавил order_by для идентификатора записи. Это необходимо, потому что может быть несколько обновлений в день. Сама дата не скажет нам, какое из этих обновлений было последним в тот же день, поэтому мы используем идентификатор, чтобы определить это. (при условии, что он хронологически инкрементален).

Теперь у нас есть список всех статусов и идентификаторов велосипедов в базе данных до 9 декабря, нам нужно ограничить это только одной записью на велосипед. Это легко, мы можем обернуть исходный запрос новым запросом с помощью директивы Group By на bike_id.

SELECT * FROM (
  SELECT * FROM bikes 
  WHERE updated_on < '20181209'
  ORDER BY updated_on DESC, id DESC
) AS sub 
GROUP BY bike_id

Group By в MySQL выбирает первую найденную запись для каждой группы. Мы уже упорядочили список по date и id в исходном запросе, поэтому первая запись для каждого bike_id будет самым последним состоянием для этого велосипеда по состоянию на 8 декабря

Теперь нам осталось только выбрать bike_id и отфильтровать неживые велосипеды, используя WHERE is_live = true в этом последнем запросе. Вот как мы получаем запрос в начале этого ответа:

SELECT bike_id FROM (
  SELECT * FROM (
    SELECT * FROM bikes 
    WHERE updated_on < '20181209'
    ORDER BY updated_on DESC, id DESC
  ) AS sub 
  GROUP BY bike_id
) AS sub2
WHERE is_live = true

Надеюсь, это поможет.

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