#mysql #join #group-by #datediff
Вопрос:
Мне нужно найти одну цену на все объекты, которая как можно ближе к желаемому диапазону дат, который ищут люди. Один объект может иметь несколько цен для разных диапазонов дат.
Таблица цен
ID | объект | Цена | начало | конец |
---|---|---|---|---|
1 | 21 | 50 | 2021-01-01 | 2021-04-01 |
2 | 21 | 60 | 2021-04-02 | 2021-08-01 |
3 | 22 | 30 | 2021-01-01 | 2021-04-01 |
4 | 23 | 150 | 2021-01-01 | 2021-04-01 |
5 | 21 | 20 | 2021-08-02 | 2021-09-01 |
6 | 23 | 120 | 2021-07-01 | 2021-08-01 |
Итак, допустим, люди ищут между 2021-05-01
, и 2021-06-01
результаты должны быть:
ID | объект | Цена |
---|---|---|
2 | 21 | 60 |
3 | 22 | 30 |
6 | 23 | 120 |
Я работаю над этим запросом, но где-то я потерял фокус.
SELECT p.objectid,
p.id
p.start,
p.end,
p.price,
ABS(DATEDIFF(p.start, '2021-05-01') DATEDIFF(p.end, '2021-06-01')) diff
FROM
prices AS p1
INNER JOIN(
SELECT
p.objectid,
MIN(
ABS(
DATEDIFF(start, '2021-05-01') DATEDIFF(end, '2021-06-01')
)
) AS diff
FROM
prices p
GROUP BY
p.objectid
) p2
ON
p1.objectid = p2.objectid AND diff = p2.diff
Ответ №1:
Вы можете достичь этого с помощью самостоятельного соединения.
Попробуйте выполнить следующий запрос
SELECT
Y.id,
Y.objectid,
Y.price
FROM
(
SELECT
*,
ABS(
DATEDIFF(`start`, '2021-05-01') DATEDIFF(`end`, '2021-06-01')
) AS `diff`
FROM
price
) AS Y
INNER JOIN(
SELECT
*,
MIN(
ABS(
DATEDIFF(`start`, '2021-05-01') DATEDIFF(`end`, '2021-06-01')
)
) AS diff
FROM
price
GROUP BY
objectid
) AS X
ON
X.objectid = Y.objectid AND X.diff = Y.diff
ORDER BY
Y.id
Комментарии:
1. Спасибо! Не могли бы вы проверить, делает ли решение, которое я опубликовал, то же самое? Пришел с этим вчера вечером.
2. Я не проверял ваш запрос, вы можете проверить себя, но если ваша проблема решена, вы можете закрыть свой вопрос, приняв мой ответ 🙂
3. Конечно, подойдет, просто хотел посмотреть, найдете ли вы или кто-то другой проблему в моем решении или лучшее.
4. Решение, которое вы ему дали, не работает, и в нем много ошибок. Ваше решение недействительно.
5. Хм, пока все идет очень хорошо.
Ответ №2:
Это решение, которое должно работать, но, я думаю, объединение различий может привести к искаженным результатам.
SELECT p.objectid,
p.id
p.start,
p.end,
p.price
FROM
prices AS p1
INNER JOIN(
SELECT
p.objectid,
MIN(
ABS(
DATEDIFF(start, '2021-05-01') DATEDIFF(end, '2021-06-01')
)
) AS diff
FROM
prices p
GROUP BY
p.objectid
) p2
ON
p1.objectid = p2.objectid AND (ABS(DATEDIFF(p.start, '2021-05-01') DATEDIFF(p.end, '2021-06-01'))) = p2.diff