MySQL - ORDER 结果基于它匹配的 OR 数量
MySQL - ORDER result based on how many ORs it match
数据库不是我的强项,我不确定我要找的东西是否存在。总的来说,如果有任何建议可以引导我走上正确的道路,我会很高兴。
我得到的:
我有一个查询有多个或者想象它像下面这样:
SELECT * FROM video WHERE video.name LIKE '%topspeed%' OR video.name LIKE '%%audi%';
让我们想象一下这个查询的结果是:
+------------+---------------+
| id | name |
+------------+---------------+
| 1 | My best audi |
| 2 | topspeed of mustang? |
| 3 | audi A7 topspeed |
| 4 | Do you like audi? |
| 5 | topspeed of audi Q8 |
+------------+---------------+
我需要的:
有没有一种方法可以根据匹配的 OR 数量来排序结果?
所以换句话说,我希望原始示例的顺序是:
+------------+---------------+
| id | name |
+------------+---------------+
| 5 | topspeed of audi Q8 |
| 3 | audi A7 topspeed |
| 1 | My best audi |
| 2 | topspeed of mustang? |
| 4 | Do you like audi? |
+------------+---------------+
考虑:
ORDER BY
(video.name LIKE '%topspeed%') + (video.name LIKE '%audi%') DESC,
id
基本原理:在数字上下文中,MySQL 条件表达式 returns 1
如果为真,否则 0
。因此,在两个条件上都匹配的视频获得 2
的值,而在一个条件上匹配的视频仅获得 1
。您可以对其使用降序排序。我在 ORDER BY
子句中添加了另一个条件,以通过打破关系来获得确定性排序。
在MySQL中,您可以这样做:
SELECT v.*
FROM video v
WHERE v.name LIKE '%topspeed%' OR v.name LIKE '%audi%'
ORDER BY (v.name LIKE '%topspeed%') + (v.name LIKE '%audi%') DESC;
MySQL 将布尔值视为数字上下文中的数字,1
表示“真”,0
表示“假”。
注意另外两个变化。我添加了一个 table 别名,这样 table 在限定列名时更容易引用。我也把 '%%audi'
改成了 '%audi%'
。连续两个 '%'
不会做任何 '%'
做的事情。
SELECT
id,
name,
(CASE WHEN video.name LIKE '%topspeed%' THEN 1 ELSE 0 END +
CASE WHEN video.name LIKE '%%audi%' THEN 1 ELSE 0 END) as score
FROM video WHERE video.name LIKE '%topspeed%' OR video.name LIKE '%%audi%'
ORDER BY score DESC;
此查询也适用于 MS-SQL,这就是我使用 CASE WHEN....END
.
的原因
数据库不是我的强项,我不确定我要找的东西是否存在。总的来说,如果有任何建议可以引导我走上正确的道路,我会很高兴。
我得到的:
我有一个查询有多个或者想象它像下面这样:SELECT * FROM video WHERE video.name LIKE '%topspeed%' OR video.name LIKE '%%audi%';
让我们想象一下这个查询的结果是:
+------------+---------------+
| id | name |
+------------+---------------+
| 1 | My best audi |
| 2 | topspeed of mustang? |
| 3 | audi A7 topspeed |
| 4 | Do you like audi? |
| 5 | topspeed of audi Q8 |
+------------+---------------+
我需要的:
有没有一种方法可以根据匹配的 OR 数量来排序结果? 所以换句话说,我希望原始示例的顺序是:+------------+---------------+
| id | name |
+------------+---------------+
| 5 | topspeed of audi Q8 |
| 3 | audi A7 topspeed |
| 1 | My best audi |
| 2 | topspeed of mustang? |
| 4 | Do you like audi? |
+------------+---------------+
考虑:
ORDER BY
(video.name LIKE '%topspeed%') + (video.name LIKE '%audi%') DESC,
id
基本原理:在数字上下文中,MySQL 条件表达式 returns 1
如果为真,否则 0
。因此,在两个条件上都匹配的视频获得 2
的值,而在一个条件上匹配的视频仅获得 1
。您可以对其使用降序排序。我在 ORDER BY
子句中添加了另一个条件,以通过打破关系来获得确定性排序。
在MySQL中,您可以这样做:
SELECT v.*
FROM video v
WHERE v.name LIKE '%topspeed%' OR v.name LIKE '%audi%'
ORDER BY (v.name LIKE '%topspeed%') + (v.name LIKE '%audi%') DESC;
MySQL 将布尔值视为数字上下文中的数字,1
表示“真”,0
表示“假”。
注意另外两个变化。我添加了一个 table 别名,这样 table 在限定列名时更容易引用。我也把 '%%audi'
改成了 '%audi%'
。连续两个 '%'
不会做任何 '%'
做的事情。
SELECT
id,
name,
(CASE WHEN video.name LIKE '%topspeed%' THEN 1 ELSE 0 END +
CASE WHEN video.name LIKE '%%audi%' THEN 1 ELSE 0 END) as score
FROM video WHERE video.name LIKE '%topspeed%' OR video.name LIKE '%%audi%'
ORDER BY score DESC;
此查询也适用于 MS-SQL,这就是我使用 CASE WHEN....END
.