SQLite SELECT…ordering by “best” match

穿精又带淫゛_ 提交于 2021-01-29 14:44:18

问题


The context here is a SQLCipher database in an Android app. The context here is a SQLCipher database in an Android app. The context here is a SQLCipher database in an Android app. Consider the following SQLite table

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

into which I insert the following rows

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

A simple SELECT COUNT(*) FROM test WHERE a = 1 OR b = 2 or c = 3 or d = 4; would return 4 as the result since 4 of the 5 rows have one or more matching values. What I need to do is to find the "best" match, i.e. the one that satisfies the most WHERE .. OR conditions. In the present instance this would return the first row where all four columns match. While I could simply get a cursor back on a raw select along the lines of SELECT * FROM test WHERE a = 1 OR b = 2 or c = 3 or d = 4; and then do the rest in Java I am wondering if there isn't a way to do this directly within SQLite itself.


回答1:


Use the expression:

(a=1) + (b=2) + (c=3) + (d=4)

in the ORDER BY clause:

SELECT *
FROM test
ORDER BY (a=1) + (b=2) + (c=3) + (d=4) DESC
LIMIT 1

Each of the terms: (a=1), (b=2), (c=3) and (d=4) evaluates to 1 for TRUE or 0 for FALSE.
See the demo.
If you want ties in the results use a CTE:

WITH cte AS (
  SELECT *, (a=1) + (b=2) + (c=3) + (d=4) counter
  FROM test
)
SELECT a, b, c, d 
FROM cte
WHERE counter = (SELECT MAX(counter) FROM cte)

See the demo.
Or with RANK() window function:

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

See the demo.
Results:

| a   | b   | c   | d   |
| --- | --- | --- | --- |
| 1   | 2   | 3   | 4   |


来源:https://stackoverflow.com/questions/60538227/sqlite-select-ordering-by-best-match

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!