首先放置一个特定的行,然后按列排序

时间:2014-12-29 17:51:04

标签: 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  |
+----+----------+------+

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

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

期望的结果将是:

+----+----------+------+
| id | store_id | rank |
+----+----------+------+
|  2 |   5      |   9  |
+----+----------+------+
|  1 |   1      |  10  |
+----+----------+------+
|  3 |   4      |   8  |
+----+----------+------+
|  4 |   3      |   7  |
+----+----------+------+
|  5 |   3      |   6  |
+----+----------+------+
|  6 |   1      |   5  |
+----+----------+------+

这里(@id:=(SELECT id FROM b WHERE store_id = 5 ORDER BY rank DESC LIMIT 1))用于选择具有store_id = 5的最高得分项目。此项目将首先出现在列表中因此,为什么通过将它乘以一个非常大的数字来重新排它。所有其他级别保持不变,并按降序排列。

问题是连接中的select语句试图从名为b的子查询中加入选择。但是,表b实际上并不存在于数据库中,因此MySQL表示表b不存在。我如何引用子查询?实际的子查询非常复杂,所以我没有把它包含在这里,但是如果有兴趣你可以在这里看到它的一个版本:MySQL - How To Optimize thie Query。这个问题中的查询只是为了简化问题。

1 个答案:

答案 0 :(得分:2)

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

ORDER BY store_id = 5 DESC, rank DESC;

将把store_id 5的行放在最上面。在此示例中,您需要store_id 5具有最高排名的行,因此我编写了以下子查询:

SELECT id
FROM myTable
WHERE store_id = 5
ORDER BY rank DESC
LIMIT 1;

我把它放在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;

这是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;

另一个Fiddle