先放置特定行,然后按列排序

use*_*306 2 mysql sql sql-order-by

编辑:目标是对输出进行排序,以便第一个结果是 store_id = 5 的行和 store_id = 5 的所有项目的最大排名。然后其余的交易根据它们的排名按降序排列,无论他们的 store_id。对于实际查询,联合会太昂贵。

数据的一个例子是:

+----+----------+------+
| id | store_id | rank |
+----+----------+------+
|  1 |   1      |  10  |
+----+----------+------+
|  2 |   5      |   9  |
+----+----------+------+
|  3 |   4      |   8  |
+----+----------+------+
|  4 |   3      |   7  |
+----+----------+------+
|  5 |   3      |   6  |
+----+----------+------+
|  6 |   1      |   5  |
+----+----------+------+
Run Code Online (Sandbox Code Playgroud)

正在运行的最终查询将是:

SELECT id,store_ID,IF(@id=id,rank=rank*9999999,rank) AS rank
FROM (
    SELECT * FROM (
        SELECT id,rank,store_id
        FROM items
    ) b
    JOIN (@id:=(SELECT id FROM b WHERE store_id = 5 ORDER BY rank DESC LIMIT 1)) AS s
)
ORDER BY rank DESC
Run Code Online (Sandbox Code Playgroud)

期望的结果是:

+----+----------+------+
| id | store_id | rank |
+----+----------+------+
|  2 |   5      |   9  |
+----+----------+------+
|  1 |   1      |  10  |
+----+----------+------+
|  3 |   4      |   8  |
+----+----------+------+
|  4 |   3      |   7  |
+----+----------+------+
|  5 |   3      |   6  |
+----+----------+------+
|  6 |   1      |   5  |
+----+----------+------+
Run Code Online (Sandbox Code Playgroud)

这里 (@id:=(SELECT id FROM b WHERE store_id = 5 ORDER BY rank DESC LIMIT 1)) 用于选择 store_id = 5 的得分最高的项目。这个项目应该出现在列表的第一个,这就是为什么它通过乘以一个非常大的数字来重新排序。所有其他排名保持不变,并根据他们的分数降序排列。

问题在于连接中的 select 语句试图连接来自名为 b 的子查询的选择。但是,数据库中实际上并不存在表 b,因此 MySQL 说表 b 不存在。如何引用子查询?实际的子查询非常复杂,所以我没有在此处包含它,但如果有兴趣,您可以在此处查看它的一个版本:MySQL - 如何优化 thie Query。这个问题中的查询只是为了使问题简单。

Ada*_*331 7

您可以调整 order by 子句以将特定行放在首位。假设您希望 store_id 5 成为第一个,您可以这样做:

ORDER BY store_id = 5 DESC, rank DESC;
Run Code Online (Sandbox Code Playgroud)

这会将 store_id 5 的行放在顶部。在这个例子中,你想要 store_id 5 的最高等级的行,所以我写了以下子查询:

SELECT id
FROM myTable
WHERE store_id = 5
ORDER BY rank DESC
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

我把它放在 ORDER BY 子句中:

SELECT *
FROM myTable
ORDER BY id = 
      (SELECT id FROM myTable WHERE store_id = 5 ORDER BY rank DESC LIMIT 1) DESC, 
   rank DESC;
Run Code Online (Sandbox Code Playgroud)

这是一个SQL Fiddle

编辑

如果在FROM子句中放置子查询,则将无法在子句的子查询中引用其别名ORDER BY。但是,以一种非常不可读的方式,您可以将相同的子查询放在那里来完成它,如下所示:

SELECT *
FROM (SELECT * FROM myTable) b
ORDER BY id = 
   (SELECT id FROM (SELECT * FROM myTable) b WHERE store_id = 5 ORDER BY rank DESC LIMIT 1) DESC, 
   rank DESC;
Run Code Online (Sandbox Code Playgroud)

另一个小提琴