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。这个问题中的查询只是为了使问题简单。
您可以调整 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)
另一个小提琴。