SQLite 按最小差异排序结果

SQLite order results by smallest difference

这个问题在很多方面都是从我的 提出来的。我有一个 table 几乎相同

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);

通常这个 table 会有多行,其中 some/all 的 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;

到目前为止没有问题。但是,由于天气栏,我还有一个要求。虽然这个值是一个整数,但它实际上是一个复合值,其中每个数字代表 "banded" 天气状况。以 weather = 20100306 为例。这里 2 代表在指南针上分成 45 度带的风向,0 代表风速范围,1 代表降水如雪等。在获得我的订购结果时我现在需要做的是考虑天气差异。以前两行为例

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... 会将前两行排在顶部,这很好。但是,如果我宁愿让 最小 与传入的 "weather condition" 30130306 不同的行呢?我显然希望第二行出现在顶部。再一次,我可以接受 WITH cte... 返回的 "raw" 结果,然后根据我在 Java 中的当前 "weather condition" 向下钻取到正确的行。然而,我又一次发现自己在想,在 SQL 中可能有一种非常巧妙的方法可以做到这一点,这超出了我的技能范围。如果有人能告诉我 how/whether 这可以仅使用 SQL.

,我将非常感激

您可以将结果第 1 个按 DENSE_RANK() 排序,第 2 个按 weather 和传入 "weather condition" 的绝对差值排序:

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 - ?);

? 替换为 传入 "weather condition" 的值。