为什么 select t.* from (SELECT IF(@a = convert(approverEuid using utf8) and @b = IFNULL(convert(startDate using utf8),'9999-99-99') and @c = IFNULL(convert(endDate using utf8),'9999-99-99') , @num := @num + 1, @num := 1) -1 AS listsort, @a := approverEuid, @b := IFNULL(startDate,'9999-99-99'), @c := IFNULL(endDate,'9999-99-99'), id, approverEuid,startDate,enddate FROM ga_mid.approver t , (SELECT @num := 0, @a := '',@b := '', @c := '') r where approverEuid = 'EU000000073' ORDER BY id, approverEuid,startDate,enddate) t; 和 select t.* from (SELECT IF(@a = convert(approverEuid using utf8) and @b = IFNULL(convert(startDate using utf8),'9999-99-99') and @c = IFNULL(convert(endDate using utf8),'9999-99-99') , @num := @num + 1, @num := 1) -1 AS listsort, @a := approverEuid, @b := IFNULL(startDate,'9999-99-99'), @c := IFNULL(endDate,'9999-99-99'), id, approverEuid,startDate,enddate FROM ga_mid.approver t , (SELECT @num := 0, @a := '',@b := '', @c := '') r ORDER BY id, approverEuid,startDate,enddate) t where t.approverEuid = 'EU000000073'; 的排序结果不相同
时间: 2024-04-13 12:25:00 浏览: 112
这是由于 MySQL 的执行顺序导致的结果不同。
在第一个查询中,子查询 `(SELECT @num := 0, @a := '',@b := '', @c := '') r` 是在筛选条件 `where approverEuid = 'EU000000073'` 之前执行的。这意味着在子查询中变量 `@num` 的值会在进行筛选操作之前递增。
而在第二个查询中,子查询 `(SELECT @num := 0, @a := '',@b := '', @c := '') r` 是在整个结果集上执行的。这意味着变量 `@num` 的值会在排序操作之前递增。
由于递增操作的不同时机,这两个查询的结果集中的 `listsort` 列的排序值可能会不同,进而导致最终结果的顺序不同。
如果你希望两个查询的排序结果相同,你可以尝试将子查询 `(SELECT @num := 0, @a := '',@b := '', @c := '') r` 移动到主查询之前,以确保变量在排序操作之前被正确初始化。或者,你也可以在两个查询中都加上筛选条件 `where approverEuid = 'EU000000073'`,以确保只返回特定的 `approverEuid` 的行并进行排序。
相关问题
select t.* from (SELECT IF(@a = convert(approverEuid using utf8) and @b = IFNULL(convert(startDate using utf8),'9999-99-99') and @c = IFNULL(convert(endDate using utf8),'9999-99-99') , @num := @num + 1, @num := 1) -1 AS listsort, @a := approverEuid, @b := IFNULL(startDate,'9999-99-99'), @c := IFNULL(endDate,'9999-99-99'), id, approverEuid,startDate,enddate FROM ga_mid.approver t , (SELECT @num := 0, @a := '',@b := '', @c := '') r where approverEuid = 'EU000000073' ORDER BY id, approverEuid,startDate,enddate) t where t.approverEuid = 'EU000000073'; 和 select t.* from (SELECT IF(@a = convert(approverEuid using utf8) and @b = IFNULL(convert(startDate using utf8),'9999-99-99') and @c = IFNULL(convert(endDate using utf8),'9999-99-99') , @num := @num + 1, @num := 1) -1 AS listsort, @a := approverEuid, @b := IFNULL(startDate,'9999-99-99'), @c := IFNULL(endDate,'9999-99-99'), id, approverEuid,startDate,enddate FROM ga_mid.approver t , (SELECT @num := 0, @a := '',@b := '', @c := '') r ORDER BY id, approverEuid,startDate,enddate) t where t.approverEuid = 'EU000000073'; 的区别
这两个查询之间的区别在于是否添加了过滤条件 `where approverEuid = 'EU000000073'`。
在第一个查询中,通过在子查询的 `WHERE` 子句中添加了条件 `where approverEuid = 'EU000000073'`,限制了最终结果集中 `approverEuid` 列的值为 `'EU000000073'`。
而在第二个查询中,没有添加这个过滤条件,因此会返回整个结果集,其中包含所有不同的 `approverEuid` 值。
由于这个过滤条件的存在与否,两个查询的结果集可能会有所不同。第一个查询只返回满足条件的行,而第二个查询返回所有行。如果你只关心 `approverEuid` 为 `'EU000000073'` 的行,那么第一个查询可能更适合你的需求。
请注意,在这两个查询中,排序操作是在子查询中进行的,然后再通过外层查询将结果限制为 `approverEuid = 'EU000000073'` 的行。因此,排序的效果并不会受到过滤条件的影响。
Oracle 下SQL语句怎么写 SELECT @ROWNUM := @ROWNUM + 1 AS TEMPRANK, @INCRNUM := CASE WHEN @ROWTOTAL = OBJ.YLCOUNT + 1 THEN @INCRNUM WHEN @ROWTOTAL := OBJ.YLCOUNT + 1 THEN @ROWNUM END AS FILERANK, OBJ.* FROM ( SELECT DOCINFO.TITLE, DOCINFO.DOC_ID AS DOCID, DOCINFO.DOC_TYPE AS DOCTYPE, U.USER_NAME AS AUTHORNAME, CONCAT( U.USER_NAME, '/', CASE WHEN O.SHORT_NAME = '' THEN '无' ELSE O.SHORT_NAME END ) AS USERNAME, IFNULL( DOCINFO.DOWNLOAD_NUM, 0 ) AS YLCOUNT FROM DOC_INFO DOCINFO, SYS_USERS U, SYS_ORGAN O, sys_stru WHERE DOCINFO.VALID_FLAG = '1' AND IFNULL( DOCINFO.DOWNLOAD_NUM, 0 ) != 0 AND U.USER_ID = DOCINFO.AUTHOR_ID AND sys_stru.STRU_ID = U.DEPARTMENT_ID AND O.ORGAN_ID = sys_stru.ORGAN_ID GROUP BY DOCINFO.DOC_ID, U.USER_NAME ORDER BY DOCINFO.DOWNLOAD_NUM DESC, DOCINFO.TITLE DESC ) OBJ, ( SELECT @ROWNUM := 0, @ROWTOTAL := NULL, @INCRNUM := 0 ) R
在 Oracle 中,可以将该 SQL 语句写成如下形式:
```
SELECT TEMPRANK, FILERANK, TITLE, DOCID, DOCTYPE, AUTHORNAME, USERNAME, YLCOUNT
FROM (
SELECT DOCINFO.TITLE, DOCINFO.DOC_ID AS DOCID, DOCINFO.DOC_TYPE AS DOCTYPE,
U.USER_NAME AS AUTHORNAME, CONCAT(U.USER_NAME, '/', CASE WHEN O.SHORT_NAME = '' THEN '无' ELSE O.SHORT_NAME END) AS USERNAME,
IFNULL(DOCINFO.DOWNLOAD_NUM, 0) AS YLCOUNT,
@ROWNUM := @ROWNUM + 1 AS TEMPRANK,
@INCRNUM := CASE
WHEN @ROWTOTAL = OBJ.YLCOUNT + 1 THEN @INCRNUM
WHEN @ROWTOTAL := OBJ.YLCOUNT + 1 THEN @ROWNUM
END AS FILERANK
FROM DOC_INFO DOCINFO, SYS_USERS U, SYS_ORGAN O, sys_stru
WHERE DOCINFO.VALID_FLAG = '1'
AND IFNULL(DOCINFO.DOWNLOAD_NUM, 0) != 0
AND U.USER_ID = DOCINFO.AUTHOR_ID
AND sys_stru.STRU_ID = U.DEPARTMENT_ID
AND O.ORGAN_ID = sys_stru.ORGAN_ID
GROUP BY DOCINFO.DOC_ID, U.USER_NAME
ORDER BY DOCINFO.DOWNLOAD_NUM DESC, DOCINFO.TITLE DESC
) OBJ, (SELECT @ROWNUM := 0, @ROWTOTAL := NULL, @INCRNUM := 0) R;
```
在 Oracle 中,变量需要在 SQL 语句外面进行声明和初始化。这里使用了 `@ROWNUM`、`@ROWTOTAL` 和 `@INCRNUM` 三个变量,它们都在 SQL 语句的最后一行进行了声明和初始化。
此外,由于 Oracle 对于 SQL 语句的执行顺序与 MySQL 略有不同,因此需要将临时变量的计算放在子查询中,并使用外层查询来获取这些变量的值。最终的结果集是从子查询中返回的。
阅读全文