这个问题在Stackoverflow上问了很多,但是我遇到了一些不同的问题。
SET @rownum = 0;
SELECT DISTINCT doc.id,
doc.created_date,
( @rownum := @rownum + 1 ) AS rownumbers
FROM document AS doc
INNER JOIN document_type_master dt
ON doc.document_type_id = dt.id
ORDER BY doc.id ASC;
以上查询为我提供了以下输出。
id created_date rownumbers
5664 2014-06-05 07:23:40 1
5665 2014-06-06 06:37:34 2
5666 2014-06-06 10:25:56 3
5667 2014-06-06 10:33:39 4
5668 2014-06-06 11:28:28 5
如果我将ORDER BY doc.id ASC
更改为ORDER BY doc.id DESC
,则输出为
id created_date rownumbers
6364 2014-11-11 17:57:04 691
6363 2014-11-11 11:09:49 690
6362 2014-11-11 10:58:34 689
6361 2014-11-10 17:39:47 688
6360 2014-11-10 16:59:53 687
我尝试了一些事情,发现如果我从查询中删除DISTINCT
,则在rownumbers
的情况下,1,2,3...
会启动ORDER BY doc.id DESC
。
id created_date rownumbers
6364 2014-11-11 17:57:04 1
6363 2014-11-11 11:09:49 2
6362 2014-11-11 10:58:34 3
6361 2014-11-10 17:39:47 4
6360 2014-11-10 16:59:53 5
我也尝试过点rownumbers
ORDER BY doc.id DESC, rownumbers ASC
,但不适合我。
我希望rownumbers
值始终为ASC
顺序,无论我是否使用DISTINCT
。
更新
@Barmar是正确的,但如果我在rownumbers
子句中使用WHERE
,如
rownumbers between 1 and 5
然后显示错误Error Code: 1054. Unknown column 'rownumbers' in 'where clause'
答案 0 :(得分:2)
在生成结果中的所有行之后完成ORDER BY
处理。首先,它通过按照数据库中的任何顺序处理数据来分配所有rownumber
列,然后反向重新排序。
这种情况仅在您使用DISTINCT
时才会发生,因为这需要它首先生成所有结果,以便它可以删除所有重复项。如果没有DISTINCT
,它可以采用快捷方式并对原始表数据执行排序。然而,虽然这通常按预期工作,但不能保证。
要获得所需的结果,您需要将ORDER BY
放入子查询中:
SET @rownum = 0;
SELECT x.*, ( @rownum := @rownum + 1 ) AS rownumbers
FROM (
SELECT DISTINCT doc.id,
doc.created_date
FROM document AS doc
INNER JOIN document_type_master dt
ON doc.document_type_id = dt.id
ORDER BY doc.id DESC) AS x
要在WHERE子句中引用rownumbers,您需要另一级子查询:
SELECT *
FROM (
SELECT x.*, ( @rownum := @rownum + 1 ) AS rownumbers
FROM (
SELECT DISTINCT doc.id,
doc.created_date
FROM document AS doc
INNER JOIN document_type_master dt
ON doc.document_type_id = dt.id
ORDER BY doc.id DESC) AS x
) AS y
WHERE rownumbers BETWEEN 1 AND 5
或者您可以使用HAVING
:
SELECT x.*, ( @rownum := @rownum + 1 ) AS rownumbers
FROM (
SELECT DISTINCT doc.id,
doc.created_date
FROM document AS doc
INNER JOIN document_type_master dt
ON doc.document_type_id = dt.id
ORDER BY doc.id DESC) AS x
HAVING rownumbers BETWEEN 1 AND 5
但是当我尝试使用来自这样的变量的别名HAVING
时,我看到了一些奇怪的行为,显然是因为MySQL采用了这些快捷方式。