Получить значения первой записи и последней записи по дате в подзапросе MySQL

0

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

Шахта выглядит иначе, чем другие, которые хотят "мин и максимум" поля, но мне нужно значение из другого поля на основе "мин и макс" поля даты.

Учитывая следующую структуру - таблицу "пользователь" и таблицу "записи":

Пример данных (для таблицы "записи"):

id | user_id |     date     | value  
---+---------+--------------+-------
 1         1     2018-02-01     125
 2         5     2018-01-15     220
 3         1     2017-12-31     131
 4         4     2018-01-01      77
 3         1     2017-12-15     133

Я хотел бы знать значение первой записи (по дате), значение последней записи (по дате) и user_id.

Результаты должны быть следующими:

user_id | first_date | first_value |  last_date | last_value
--------+------------+-------------+------------+-----------
      1   2017-12-15           133   2018-02-01          125
      4   2018-01-01            77   2018-01-01          133
      5   2018-01-15           220   2018-01-15          220

Хотя я хочу лучшее решение, то, над чем я работал, вращается вокруг объединения таких запросов:

SELECT user_id, l.date AS last_date, l.value AS last_value, f.date AS first_date, f.value AS first_value  
    FROM user AS u
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1) AS f ON f.user_id = u.user_id
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date DESC LIMIT 1) AS l ON l.user_id = u.user_id

ПРИМЕЧАНИЕ. Это не работает. Если бы я захотел "первой записи" для кого-то, я бы написал запрос, который был SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1 - однако использование его в подзапросах не имеет желаемого эффекта.

Я также пробовал некоторые запросы GROUP BY, но не имел успеха.

SQL Fiddle: http://sqlfiddle.com/#!9/71599

  • 0
    См. Meta.stackoverflow.com/questions/333952/… (кажется странным указывать на 17.5k)
  • 1
    @fubar - спасибо за скрипку!
Теги:
mariadb
subquery

1 ответ

1
Лучший ответ

Следующий запрос дает ожидаемый результат, но он выполняется без использования LEFT JOIN. Таким образом, значения NULL исключаются.

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM 
    users u, 
    (SELECT * FROM entries e ORDER BY date ASC) e1,
    (SELECT * FROM entries e ORDER BY date DESC) e2
WHERE
    e1.user_id = u.id
AND 
    e2.user_id = u.id
GROUP BY 
    u.id

И вот рабочая скрипка - http://sqlfiddle.com/#!9/71599/8

Кроме того, стоит отметить, что LIMIT в вашей попытке ограничит результаты 1 для всех объединенных результатов, а не для каждого объединенного результата. В любом случае, LEFT JOIN не работает. Если кто-нибудь знает, почему, мне было бы интересно понять.

Edit: Здесь другая попытка, на этот раз с использованием MIN() и MAX(), а не ORDER BY. К сожалению, для этого вам нужно несколько раз присоединиться к таблице entries.

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM users u
INNER JOIN entries e1 ON (u.id = e1.user_id)
INNER JOIN entries e2 ON (u.id = e2.user_id)
INNER JOIN (
    SELECT user_id, MIN(date) AS date
    FROM entries
    GROUP BY user_id
) e3 ON (e1.user_id = e3.user_id AND e1.date = e3.date)
INNER JOIN (
    SELECT user_id, MAX(date) AS date
    FROM entries
    GROUP BY user_id
) e4 ON (e2.user_id = e4.user_id AND e2.date = e4.date)
GROUP BY u.id

Еще одна рабочая скрипка: http://sqlfiddle.com/#!9/71599/18

  • 0
    Еще раз спасибо. Любая идея, почему это не будет работать на MariaDB через PHPMyAdmin? Я получаю одинаковые записи / значения как для «первого», так и для «последнего».
  • 0
    В быстром Google это звучит так, будто MariaDB игнорирует предложения ORDER BY в подзапросах. Вернуться к доске для рисования.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню