mySQL分页机制与模糊查询+oracle分页机制与模糊查询

7 篇文章 0 订阅
2 篇文章 0 订阅
分页一:
Mysql分页采用limt关键字  select * from t_order limit 5,10; #返回第6-15行数据 select * from t_order limit 5; #返回前5行 select * from t_order limit 0,5; #返回前5行  Mssql 2000分页采用top关键字(20005以上版本也支持关键字rownum)  Select top 10 * from t_order where id not in (select id from t_order where id>5 ); //返回第6到15行数据  其中10表示取10记录 5表示从第5条记录开始取
Oracle分页

①采用rownum关键字(三层嵌套) SELECT * FROM( SELECT A.*,ROWNUM num FROM (SELECT * FROM t_order)A WHERE ROWNUM<=15) WHERE num>=5;--返回第5-15行数据 ②采用row_number解析函数进行分页(效率更高) SELECT xx.* FROM( SELECT t.*,row_number() over(ORDER BY o_id)AS num FROM t_order t )xx WHERE num BETWEEN 5 AND 15; --返回第5-15行数据 解析函数能用格式 函数() over(pertion by 字段 order by 字段); Pertion 按照某个字段分区 Order 按照勒个字段排序 用分析函数 一万条后翻最后一页会很慢,使用ROWNUM 一万条之后每翻一页都会慢

     分页二:          

Oracle分页查询:
                  sql查询语句关键字:  runnum    
                  Oracle两种分页查询:
                                                    ① SELECT   *   FROM  (  SELECT  A. * , ROWNUM RN  FROM  ( SELECT   *   FROM  TABLE_NAME) A  WHERE  ROWNUM  <=   40  )  WHERE  RN  >=   21
                               注解:其中最内层的查询 SELECT   *   FROM  TABLE_NAME 表示不进行翻页查询语句, ROWNUM  <=   40  )  WHERE  RN  >=   21 控制分页查询每页的范围
                                     第二层用来控制分页查询的最大值,最外层用来控制分页查询的最小值
                             SELECT   *   FROM  (  SELECT  A. * , ROWNUM RN  FROM  ( SELECT   *   FROM  TABLE_NAME) A )  WHERE  RN  BETWEEN   21   AND   40
            对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。

 

这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。
 
而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。
 
上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。
 
这里就不对包含排序的查询进行说明了,下一篇文章会通过例子来详细说明。下面简单讨论一下多表联合的情况。对于最常见的等值表连接查询,CBO一般可能会采用两种连接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑)。在这里,由于使用了分页,因此指定了一个返回的最大记录数,NESTED LOOP在返回记录数超过最大值时可以马上停止并将结果返回给中间层,而HASH JOIN必须处理完所有结果集(MERGE JOIN也是)。那么在大部分的情况下,对于分页查询选择NESTED LOOP作为查询的连接方法具有较高的效率(分页查询的时候绝大部分的情况是查询前几页的数据,越靠后面的页数访问几率越小)。
分页查询实体类及方法:
     实体类属性:当前页currentPage、总页数totalPage、每页显示条数pageSize、总行数totalRows、显示开始位置startNum、显示结束位置endIndex、下一页nextPage、上一页previousPage、
查询记录数queryRecordSize、是否有下一页hasNextPage 、是否有上一页hasPreviousPage
            
      实体类方法: 重编页码repaginate()
                          1.计算总页数
                                       if: 如果查询数据的总行数%每页显示数据条数为0,则总页数等于查询数据的总行数/每页显示数据条数
                      else: 如果查询数据的总行数%每页显示数据条数为0,则总页数等于查询数据的总行数/每页显示数据条数+1   注:当查询条数为12,每页显示的数据条数为10。则此时的页数应该数2
                          2.判断是否有下一页
                                       if: 当当前页码大于或等于总的页数,则是、此时没有下一页且当前页码为总页数,否则有下一页
                          3.判断是否有上一页
                                        if: 当当前页<=1时,也就是当前页是首页,则没有上一页,当前页码数为1,否则有上一页
                          4.计算分页查询每页开始的位置
                                        if: 如果当前页为首页,则从下表为0开始查询  否则查询开始位置为  (当前页面数-1)*每页显示总数-1  
                          5.计算分页查询每页结束的位置
                                        注:分三种情况    1.当前页是首页   2.当前页是最后一页   3.当前页是中间页
                           当前页是中间页   结束位置为当前页码数*每页显示条数
                           当前页是最后一页    开始位置为(当前页面数-1)*每页显示总数     结束位置为查询数据总条数
                           当前页为首页      结束位置为每页显示条数
                          6.下一页页码加1      当当前页是尾页     没有下一页
                          7.上一页页码减1      //当前页为首页   没有上一页
                          8.设置显示开始位置     开始位置=每页显示条数*(当前页码-1)+1
                          9.设置显示结束位置     结束位置=每页显示条数*当前页码
Mysql分页查询:
                         sql查询关键字: limit 参数一,参数二
                         注解:参数一是开始查询的位置、参数二是从参数一+1条数据开始查询参数二条数据
sql查询语句:
                         select *    from table_name limit   m,n
实体类属性:当前页码pageNo、泛型分钟实体类集合list、每页显示条数pageSize、总页数totalItemNumber、
实体类方法

分页三:

Oracle和Mysql主键、索引及分页的区别

 
区别:
       1、主键,Oracle不可以实现自增, mysql可以实现自增。
  www.2cto.com  
oracle新建序列,SEQ_USER_Id.nextval 
 
       2、索引:
 
mysql索引从0开始,Oracle从1开始。
 
3、分页,
 
mysql: select * from user order by desc limit n ,m.     
 
       表示,从第n条数据开始查找,一共查找m条数据。
  www.2cto.com  
Oracle:select * from user 
 
select rownum a * from ((select * from user)a)
 
select * from (select  rownum a.* from (select * from user) a )
 
where r between  n , m .
 
表示,n表示从第n条数据查询,查找到m条数据。

分页四:

一、MySQL

MYSQL中有特定的分页查询语句,该sql语句只能在MySQL中使用

select * from t_customer limit ?,?

该sql语句的意思是,从第几行开始,然后取多少行,MySQL中第一行的下标是0

例如:我要取数据库中的前10行数据,我的sql语句应该这样写:select  *  from  t_customer  limit 0,9;

二、Oracle

select * from(select rownum id, t_customer.* from t_customer where rownum <= ? )where id >= ?;

例如:查询第20行到第30行的数据

select * from(select rownum id, t_customer.* from t_customer where rownum <= 30 )where id >= 20;

在做查询记录集的展现时,分页实现是常做的工作了。不同的数据库,分页的实现也不尽相同,这里我们对比Myslq和Oracle来简要说明一下两种常用数据库中的分页实现

1.MySQL中的limit关键字

以模糊查询为例子,limit写到where子句的后面

select * from user where name like '%mm%' limit startrow,readsize;

其中值得推敲的是startrow和readsize也就是开始和读取的记录数

这样查询出来的结果集是从startrow行,读取endsize条记录,实际上查询到的结果集是startrow+1到startrow+readsize的结果,这是操作中我们应该注意的,结果集不包括startrow.

2.Oracle中的rownum关键字

select name,email from (select rownum rn ,name ,email  from user  where rownum <endrow) t where t.rn>=sartrow

这样我们就可以得到startrow到endrow结果集,注意结果集合不包括endrow当前行记录,如果条件子句中不是>=startrow,那么查询到的结果集是也不包括startrow当前行记录。

Oracle中主要用到rownum这个伪字段,子查询得到的记录集包括了一个rownum字段,由于Oracle中rownum字段都是从1开始递增的,查询到几条记录就递增到几,所以我们应从后向前截取要查询的记录,并将rownum固定为结果集合的一个字段,然后再使用外层查询就可以以结果集的rownum固定住的字段来利用where子句来操纵记录了。

 

Mybatis中oracle、mysql、db2、sql server的like模糊查询

  1. <!-- oracle -->  
  2. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  3.   select * from t_user where user_name like CONCAT('%',#{search_name},'%')  
  4. </select>  
  5. <!-- 或者 -->  
  6. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  7.   select * from t_user where user_name like '%'||#{search_name}||'%'   
  8. </select>  
  9.   
  10. <!-- mysql -->  
  11. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  12.   select * from t_user where user_name like CONCAT('%',#{search_name},'%')  
  13. </select>  
  14.     
  15. <!-- sql server -->  
  16. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  17.   select * from t_user where user_name like '%'+#{search_name}+'%'  
  18. </select>  
  19.   
  20. <!-- db2 -->  
  21. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  22.   select * from t_user where user_name like CONCAT('%',#{search_name},'%')    
  23. </select>  
  24. <!-- 或者 -->  
  25. <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="com.urm.entity.User">  
  26.   select * from t_user where user_name like '%'||#{search_name}||'%'   
  27. </select>  

Oracle数据库,忽略大小写Like模糊查询(SQL Server,MySql原理相同)

背景

在使用Oracle或者其它数据库时,使用like 关键字进行模糊查询是大家经常使用的功能,在纯中文环境中使用非常好用,还有一些通配符可以使用,但是在纯英文环境中,会出现大小需要精确匹配的问题,主要原因还是字符串的问题

FL like '%{0}%' and

这里like后是一个字符串,这样必然会有大小敏感的问题。比如如下的大小混编的字段

xxx

 

解决方案

方案1

使用Oracle系统函数对需要查询的列字符串进行小写转换(大写也行,变量相关部分都是大写转换),如下所示:

select * from logo where lower(bsname) like '%cz%'

 

当然这样还是不够的需要将代码中变量也转换成相应的小写

String.Format(" select * from logo where lower(bsname) like '%{0}%'", tbfl.ToLower());

该方案的优点:

     数据库兼容性好,sql server和mysql都可以按相应的原理来实现

缺点:

     sql和代码中添加额外的函数代码,看起来不是这么干净

方案2

使用Oracle 正则表达式语法,完成大小写的模糊匹配 ,具体例子如下

   String.Format(" regexp_like(BSNAME,'[:graph:]*{0}[:graph:]*' ,'i') and", tbbs);

看到这里可能有人会觉得写的太浅了,可能觉得“regexp_like”,“[:graph:]*”是什么鬼?

其实以本人实用主义的观点出发完全已经够用了,达到实现like模糊查询的大小写匹配也就够了。

查阅了相关资料,发现oracle的正则表达式竟然对应java的(和c#的命名有些区别),这里

regexp_like是oracle正则匹配的函数

[:graph:]*是匹配任意字符串(0或者n个字符)

“i”参数是忽略字符串大小的意思

具体如果想了解oracle 正则表达式的使用,参考资料我会附上一些外链。这里其实也是我想吐槽的地方,可能也是作为一个实用主义者的一些想法吧,当时我做这个需求的时候,baidu到基本是方案2,但是一些资料基本都是把oracle 正则表达式列出来解释一遍,其实我要的就是一个正则模拟like的功能而已,我想如果作为一个不是精通正则的新手,学习一大堆也未必能用的上,所以我才有把这篇文章分享出来想法,如果有需求就拿去用好了,如果真需要正则,那再深入学习。

该方案的优点:

     使用简单,语句干净,考虑的地方少

缺点:

     数据库不兼容(别的数据库可能函数不同,需要查阅资料)

SQL模糊查询,使用like比较关键字,加上SQL里的通配符,请参考以下: 
1、LIKE'Mc%' 将搜索以字母 Mc 开头的所有字符串(如 McBadden)。 
2、LIKE'%inger' 将搜索以字母 inger 结尾的所有字符串(如 Ringer、Stringer)。 
3、LIKE'%en%' 将搜索在任何位置包含字母 en 的所有字符串(如 Bennet、Green、McBadden)。 
4、LIKE'_heryl' 将搜索以字母 heryl 结尾的所有六个字母的名称(如 Cheryl、Sheryl)。 
5、LIKE'[CK]ars[eo]n' 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。 
6、LIKE'[M-Z]inger' 将搜索以字符串 inger 结尾、以从 M 到 Z 的任何单个字母开头的所有名称(如 Ringer)。 
7、LIKE'M[^c]%' 将搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如MacFeather)。 
------------------------------------------------- 
下 面这句查询字符串是我以前写的,根据变量 zipcode_key 在邮政编码表 zipcode 中查询对应的数据,这句是判断变量 zipcode_key 为非数字时的查询语句,用 % 来匹配任意长度的字符串,从表中地址、市、省三列中查询包含关键字的所有数据项,并按省、市、地址排序。这个例子比较简单,只要你理解了方法就可以写出更 复杂的查询语句。 

sql = "select * from zipcode where (address like'%" & zipcode_key & "%') or (city like'%" & zipcode_key & "%') or (province like'%" & zipcode_key & "%') order by province,city,address
存储过程中使用模糊查询的例子:

SELECT * FROM Questions where QTitle like ' % [ '+ @KeyWord +' ] % ' and IsFinish = @IsFinsih

语句中成对的方括号 是书写格式的关键。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值