MySQL — диапазон дат поиска и группировка по наименьшей разнице

#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
 

O/p — это
введите описание изображения здесь

Комментарии:

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