SQL, порядок по – как предоставить больше полномочий другим столбцам?
-
22-07-2019 - |
Вопрос
У меня есть этот оператор SQL:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY date ASC, priority DESC
Это просто сортировка по дате, но я хочу придать моему столбцу «приоритет» больше авторитета.Как я могу это сделать?
Сначала он должен упорядочиваться по дате, но если время между двумя записями составляет 10 минут, я хочу, чтобы приоритет вступил во владение.Как я могу сделать это в своем операторе SQL или это должно быть в логике моего приложения?Я надеялся, что смогу сделать это в своем операторе SQL.
Спасибо всем за любую помощь
Решение
Вы можете квантовать порядок «даты» на 10-минутные куски, так как насчет упорядочения по этажу (unix_timestamp(date)/600), а затем по приоритету
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY floor(unix_timestamp(date)/600) ASC, priority DESC
Хотя две даты могут быть разделены менее чем на 10 минут, но охватывать два разных 10-минутных «куска».Возможно, этого достаточно, но я думаю, что делать именно то, что вы просите, лучше с помощью приложения.
(ОП запросил расширенное объяснение....)
Возьмем два времени, которые находятся между десятиминутным интервалом, например, 9:09 и 9:11 сегодня:
- пол(unix_timestamp('2009-03-16 09:09:00')/600) = 2061990
- пол(unix_timestamp('2009-03-16 09:11:00')/600) = 2061991
Предположим, у вас была строка с более высоким приоритетом для 09:11, чем для 09:09 — она все равно появится. после строка 09:09, потому что она попала в следующий 10-минутный фрагмент, хотя разница была всего в 2 минуты.
Таким образом, этот подход является приближением, но не решает проблему, как было заявлено изначально.
Как вы изложили свою проблему, строка с высоким приоритетом могла появиться раньше, чем записанная на несколько часов (или дней, или месяцев!) ранее, если существовала непрерывная серия строк с более низким приоритетом с интервалом менее 10 минут.
Другие советы
Еще один вариант:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY (unix_timestamp(date)/60) - priority
Все еще не совсем то, что вам нужно, но довольно близко.
Предполагая, что вы действительно имели в виду, что "время между двумя записями составляет 10 минут [или меньше], чем я хочу, чтобы приоритет занял?"
затем просто отсортируйте по десяти минутам блоков, а затем по приоритету ...
Выберите ...
Порядок по DateDiff (мин. 0, дата) / 10, приоритет
вы можете отрегулировать значение 0, чтобы указать, где находится каждый «блок тем-минут». начинается и останавливается ... Если MySql не имеет функцию DateDiff, использовать любые выражения в MySQL, который обеспечивает подсчет минут после некоторого отсчета времени ...
Если вы используете SQL Server 2005/2008, вы можете выполнить эту задачу с помощью рекурсивного CTE.Обратите внимание: я написал этот текст в блокноте, и он еще не проверен.Как только у меня появится возможность проверить результаты запроса, я обновлю CTE, если возникнет ошибка, или вообще удалю этот комментарий.
С date_cte
КАК
(SELECT *
, 'sequential_order' = ROW_NUMBER() OVER
(PARTITION BY email
ORDER BY date ASC, priority DESC)
FROM converts
WHERE email = 'myemail@googlemail.com'
AND status <> '1')
, recursive_date_cte
КАК
(SELECT dc1.*
, 'sort_level' = 1
FROM date_cte dc1
WHERE sequential_order = 1
UNION
SELECT dc1.*
, 'sort_level' = CASE
WHEN DATEDIFF(MINUTE, dc1.date, dc2.date) <= 10 THEN sort_level
ELSE sort_level + 1 END
LEFT JOIN date_cte dc2
ON dc1.sequential_order = dc2.sequential_order - 1
WHERE dc1.sequential_order > 1)
ВЫБИРАТЬ *
ОТ recursive_date_cte
Упорядочить по уровню сортировки ASC
, priority DESC
просто измените порядок столбцов в выписке порядка
SELECT * FROM converts WHERE email='myemail@googlemail.com' AND status!='1' ORDER BY priority DESC, date ASC