Результаты порядка SQLite по наименьшей разнице - PullRequest
0 голосов
/ 05 марта 2020

Этот вопрос во многом вытекает из моего предыдущего . У меня есть таблица, которая в значительной степени идентична

CREATE TABLE IF NOT EXISTS test
(
 id INTEGER PRIMARY KEY,
 a INTEGER NOT NULL,
 b INTEGER NOT NULL,
 c INTEGER NOT NULL,
 d INTEGER NOT NULL,
 weather INTEGER NOT NULL);

, в которой я обычно имел бы такие записи, как

INSERT INTO test (a,b,c,d,weather) VALUES(1,2,3,4,30100306);
INSERT INTO test (a,b,c,d,weather) VALUES(1,2,3,4,30140306);
INSERT INTO test (a,b,c,d) VALUES(1,2,5,5,10100306);    
INSERT INTO test (a,b,c,d) VALUES(1,5,5,5,11100306);
INSERT INTO test (a,b,c,d) VALUES(5,5,5,5,21101306);

Как правило, эта таблица будет иметь несколько строк с некоторыми / всеми из b , c и значения d идентичны, но имеют разные значения a и погоды. Что касается ответа на другой мой вопрос, я, безусловно, могу выдать

WITH cte AS (SELECT *, DENSE_RANK() OVER (ORDER BY (b=2) + (c=3) + (d=4) DESC) rn FROM test where a = 1) SELECT * FROM cte WHERE rn < 3;

Пока никаких проблем. Тем не менее, у меня есть еще одно требование, которое возникает в результате столбца погоды. Хотя это значение является целым числом, на самом деле оно является составным, где каждое значение di git представляет собой «полосатые» погодные условия. Возьмите для примера weather = 20100306. Здесь 2 представляет направление ветра, разделенное на 45-градусные полосы на компасе, 0 представляет диапазон скорости ветра, 1 обозначает осадки в виде снега et c. Что мне нужно сделать сейчас, чтобы получить заказанные результаты, так это учесть разницу в погоде. Возьмем, к примеру, первые две строки

INSERT INTO test (a,b,c,d,weather) VALUES(1,2,3,4,30100306);
INSERT INTO test (a,b,c,d,weather) VALUES(1,2,3,4,30140306);

Хотя в остальном они похожи, они представляют собой довольно разные погодные условия - четвертое число равно четырем, а не 0, что указывает на более высокую интенсивность осадков. WITH cte... выше будет ранжировать первые две строки в верхней части, что хорошо. Но что, если я предпочел бы иметь строку, которая отличается минимум от входящего "погодного условия" 30130306? Я бы хотел, чтобы второй ряд появлялся сверху. Еще раз, я могу жить с «сырым» результатом, возвращаемым WITH cte..., а затем перейти к правому ряду на основе моего текущего «погодного условия» в Java. Тем не менее, снова я обнаружил, что думаю, что в SQL, возможно, есть довольно аккуратный способ сделать это, не зависящий от моих навыков. Я был бы очень признателен всем, кто мог бы рассказать мне, как / можно ли это сделать, используя SQL.

1 Ответ

1 голос
/ 05 марта 2020

Вы можете отсортировать результаты 1-й по DENSE_RANK() и 2-й по абсолютной разнице weather и входящему «погодному условию»:

WITH cte AS (
  SELECT *, 
    DENSE_RANK() OVER (ORDER BY (b=2) + (c=3) + (d=4) DESC) rn 
  FROM test 
  WHERE a = 1
) 
SELECT a,b,c,d,weather 
FROM cte 
WHERE rn < 3
ORDER BY rn, ABS(weather - ?);

Заменить ? на значение этого входящие "погодные условия" .

...