`
zhouchaofei2010
  • 浏览: 1086294 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

诡异的fetch first n rows only !!

阅读更多

诡异的fetch first n rows only  !!

 

前天解决了系统一个历史科目分页查询的bug,虽然当时解决了,但并不知道造成bug的具体原因。于是,这两天通过查资料和测试终于知道了bug产生的原因

 

 

bug描述:系统在分页查询的时候,从第2页开始,以后的每一页数据都和第2页数据相同的,正确的情况应该是每页都不相同的

 

数据描述:历史科目表中的数据每天都会有数据生成,生成数据的时候会专门给数据指定一个排序号,放入列sortNum中。所以在同一天内排序号都是不同的,但是天与天之间,对应同一个科目号的排序号sortNum有大量的重复

 

                            

原始有bug的sql如下:                                          

                                          

select * from (                                 

select tba.*, ROW_NUMBER() OVER() AS ROWNUM from

(                                                                                         

  select * from 历史科目表 where 1=1             

  and glcode = '3801'                                                                  

  order by  sortNum                                                                       

) tba fetch first 50 rows only                

) where ROWNUM >40 and ROWNUM <=50    

 

 

当时解决的办法,是在子查询的order by后面多添加了日期acdate,结果正确了

 

select * from (                                 

select tba.*, ROW_NUMBER() OVER() AS ROWNUM from

(                                                                                         

  select * from 历史科目表 where 1=1             

  and glcode = '3801'                                                                  

  order by  sortNum ,acdate                                                                      

) tba fetch first 50 rows only                

) where ROWNUM >40 and ROWNUM <=50    

 

可是面对如此奇怪的问题,到底出现了在哪呢?

 

经过实验发现,如下2个对sql的改动都能使结果正确

 

1、把order by  sortNum 子句在 放入 OVER()函数中,如下

select * from (                                 

select tba.*, ROW_NUMBER() OVER(order by  sortNum ) AS ROWNUM from

(                                                                                         

  select * from 历史科目表 where 1=1             

  and glcode = '3801'                                                                  

  order by  sortNum                                                                     

) tba fetch first 50 rows only                

) where ROWNUM >40 and ROWNUM <=50  

 

 

2、把 fetch first 50 rows only 的语句去掉

 

select * from (                                 

select tba.*, ROW_NUMBER() OVER() AS ROWNUM from

(                                                                                         

  select * from 历史科目表 where 1=1             

  and glcode = '3801'                                                                  

  order by  sortNum                                                                     

) tba                

) where ROWNUM >40 and ROWNUM <=50  

 

 

怀疑是fetch first n rows only这条语句搞的鬼,于是进行了如下的数据比对

 

把 select * from 历史科目表 where 1=1 and glcode = '3801' order by sortNum 查询结果前10条记录复制日期列到UtraEdit中

 

和把select * from 历史科目表 where 1=1 and glcode = '3801' order by sortNum fetch first 10 rows only查询结果的日期列也复制到UtraEdit中,在UtraEdit的列模式下进行比对

 

 

发现10条数据是一样的,但排序不一样了,后来把测试范围扩大到20,30,40,50条,发现一个规律,加不加fetch first n rows only最后取得的结果记录都是一样的,但是加了fetch first n rows only后,会对原来order by 相同列的记录的换了一种方式排序。原来order by如果列有相同值就按物理顺序排的(即先插入的数据排在前面),但是 加了fetch first n rows only 后竟然改变了对查询结果的排序方式,在ordery by 字段值相同的时候,90% 以上的数据是按键值(这里是日期acdate)倒序排序的。所以按照

 

select * from (                                 

select tba.*, ROW_NUMBER() OVER() AS ROWNUM from

(                                                                                         

  select * from 历史科目表 where 1=1             

  and glcode = '3801'                                                                  

  order by  sortNum                                                                       

) tba fetch first 50 rows only                

) where ROWNUM >40 and ROWNUM <=50  

 

查出的结果,如果sortNum都相同的话,永远取到日期acdate 最小的那10条数据,所以分页查询的时候,就表现为点后面几页的按钮,显示的结果都是一样的状况

 

 

原来如此! 诡异的fetch first n rows only  !! 但不知道这是db2的故意优化呢,还是DB2的bug,其他的数据库oracle、sqlserver也会是这样吗的,没有环境这里就暂时先不测试了。如果有网友能有这方面的测试数据,分享一下,那就太感激了!!

 

周末愉快~ ^-^ 

2
3
分享到:
评论

相关推荐

    SQL Server 2012使用Offset/Fetch Next实现分页数据查询

    在Sql Server 2012之前,实现分页主要是使用ROW_NUMBER(),在SQL Server2012,可以使用Offset …Rows Fetch Next … Rows only的方式去实现分页数据查询。 select [column1] ,[column2] ... ,[columnN] from ...

    oracle登录问题.doc

    基本的登录时可能出现的问题,sql plus,sql developer

    Oracle数据库最优化参数缩短反应时间

    使用FIRST_ROWS_n最优化,Oracle查询能够使用最少的反应时间来给出最初的n行结果。更快速的给出最初n行的结果能够提高用户对应用软件的满意程度的原因是由于用户能够更为快速的得到最初的那些数据。 当使用FIRST_...

    Sqlserver Tsql 分页

    1.between and方法 2.offset xx rows fetch next xx rows only方法

    JAVA写的连连看游戏及源码

    rows = (int) (Math.random() * 5 + 1); while (grid[cols][rows] != 0) { cols = (int) (Math.random() * 6 + 1); rows = (int) (Math.random() * 5 + 1); } this.grid[cols][rows] = ...

    bootstrap-table-reorder-rows.js

    bootstrap-table-reorder-rows.js ,bootstraptable行拖动

    使用 childNodes 和 rows,cells 操作表格列着色源代码

    本文包含两个源代码:使用 childNodes 操作表格列着色、使用 rows,cells 操作表格列着色。两种着色方式有什么区别?具体分析请参阅作者博客:http://blog.csdn.net/defonds/archive/2010/07/17/5741214.aspx。

    Palindrome Sub-Array

    Given a 2-D array of N rows and M columns, your task is to find a maximum sub-array of P rows and P columns, of which each row and each column is a palindrome sequence. Input  The first line of ...

    sqlrows:分析器:通过报告有关* sql.Rows使用错误的诊断信息,帮助发现错误

    sqlrows sqlrows是一个静态代码分析器,它通过报告sql.Rows使用错误的诊断信息来帮助发现错误。 安装 您可以通过go get命令获取sqlrows 。 $ go get -u github.com/gostaticanalysis/sqlrows 快速开始 当Go为1.12...

    mysql SELECT FOUND_ROWS()与COUNT()用法区别1

    那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:代码如下mysql&gt; SELECT SQL_

    mysql_num_rows VS COUNT 效率问题分析

    或者 分别什么时候用num_rows 和 count( * )呢 一个直观的对比 测试数据: 条数:139764条 数据表大小:500M 结果: fetch_num_rows 用时:35.272329092026 count(*) 用时:0.071956872940063 如果单纯统计数量 ...

    Python从Excel中读取日期一列的方法

    如下所示: import xlrd import datetime ...nrows=table.nrows #行数 print nrows ncols = table.ncols#列数 print "有%s列"%ncols #只是想测试,随便输出不输出 #从Excel中读取日期格式,需要转换成Python

    python3读取excel文件只提取某些行某些列的值方法

    今天有一位同学给了我一个excel文件,要求读取某些行,某些列,然后我试着做了一个demo,这里分享出来,希望能帮到大家:...# nrows = table.nrows #行数 # ncols = table.ncols #列数 # c1=arange(0,nrows,1) # print

    python xlwt

    一个excel文件,用于显示python xlwt库生成excel文件时选取颜色和宽高...

    Expandable Detail Table Rows

    A common UI is to have a table of data rows, which when clicked on expand to show a detailed breakdown of “child” rows below the “parent” row. The only requirements ...

    python读取xlsx的方法

    nrows = tables.nrows for i in range(nrows):  if i == 0:  continue  # 第i行第j列  print(str(table.row_values(i)[j]).strip()) 以上这篇python读取xlsx的方法就是小编分享给大家的全部内容了,希望能给...

    excel poi copy rows

    using excel poi for rows copy.

    C++访问MySQL

     while(mysql_row = mysql_fetch_row(mysql_ret))   {   printf("%st%st%st%st%st%sn",mysql_row[0],mysql_row[1],mysql_row[2],mysql_row[3],mysql_row[4],mysql_row[5]);   }   }   else   {   ...

Global site tag (gtag.js) - Google Analytics