sql查询语句如何解析成分页查询?

我们公司主要mysql存储数据,因此也封装了比较好用mysql通用方法,然后,我们做大量接口,在处理分页查询接口,没有很好分查询方法。sql查询 语句如何解析成“分页查询”和“总统计”两条语句。可能,很多人在处理“总统计”是这样:“select count(*) from (<sql原查询语句>) ”,而不是把原sql查询语句中columns替换成“count(*)”;相比前者统计查询效率高不高,大家心知肚明。“分页查询”很简单,对于mysql语句就是在原sql查询语句后面加上“limit 数字 offset 数字”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MySqlTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string sql = "select id,code,name,modifytime,storeid from retail_cashier where [email protected] and  [email protected] order by id";
            var parts = MysqlPageHelper.BuildPageQuery(sql, 1, 20);

            Console.WriteLine("sql:{0};",parts.Sql);
            Console.WriteLine("SqlCount:{0}", parts.SqlCount);
            Console.WriteLine("SqlPage:{0}",parts.SqlPage);
            Console.WriteLine("SqlOrderBy:{0}", parts.SqlOrderBy);
            Console.ReadKey();
        }
    }

    public class MysqlPageHelper
    {
        public Regex RegexColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b",
            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        public Regex RegexDistinct = new Regex(@"\ADISTINCT\s",
            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        public Regex RegexOrderBy =
            new Regex(
                @"\bORDER\s+BY\s+(?!.*?(?:\)|\s+)AS\s)(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*",
                RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        private string _sqlSelectRemoved = null;
        public void SplitSql(string sql, long skip, long take)
        {
            this.Sql = sql;
            this.SqlCount = null;
            this.SqlOrderBy = null;

            // 从中提取列
            var m = RegexColumns.Match(this.Sql);
            if (!m.Success)
                throw new Exception("无法解析分页查询的SQL语句");

            // sql语句中columns替换成count(*)
            var g = m.Groups[1];
            this._sqlSelectRemoved = this.Sql.Substring(g.Index);

            if (RegexDistinct.IsMatch(this._sqlSelectRemoved))
                this.SqlCount = this.Sql.Substring(0, g.Index) + "COUNT(" + m.Groups[1].ToString().Trim() + ") " + sql.Substring(g.Index + g.Length);
            else
                this.SqlCount = this.Sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length);

            // sql语句最后order by
            m = RegexOrderBy.Match(this.SqlCount);
            if (m.Success)
            {
                g = m.Groups[0];
                this.SqlOrderBy = g.ToString();
                this.SqlCount = this.SqlCount.Substring(0, g.Index) + this.SqlCount.Substring(g.Index + g.Length);
            }
            //分页读取数据
            SqlPage = string.Format("{0}\nLIMIT {1} OFFSET {2}", this.Sql, take, skip);
        }

        public static MysqlPageHelper BuildPageQuery(string sql, long skip, long take)
        {
            var page=new MysqlPageHelper();
            page.SplitSql(sql,skip,take);
            return page;
        }

        public string Sql { get; private set; }
        public string SqlPage { get;private set; }
        public string SqlCount { get;private set; }
        public string SqlOrderBy { get;private set; }
    }
}
时间: 2024-10-12 10:57:05

sql查询语句如何解析成分页查询?的相关文章

sql优化之大数据量分页查询(mysql)

当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时就需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点. 谈优化前的准备工作 为了对下面列举的一些优化进行测试,需要使用已有的一张表作为实际例子. 表名:order_history. 描述:某个业务的订单历史表. 主要字段:unsigned int id,tinyint(4) int type. 字段情况:该表一共37个字段,不包含text等大型数据,最大为varchar(500

sql查询语句学习,多表查询和子查询以及连接查询

一.交叉连接查询 这种查询方式基本不会使用,原因就是这种查询方式得到的是两个表的乘积(笛卡儿集) 语法就是select * from a,b: 二.内连接查询,可以有效的去除笛卡尔集现象 内连接查询分为两类: 隐式内连接 select * from A,B where 条件 隐式连接使用别名:select * from A 别名1,B 别名2 where 别名1.xx=别名2.xx: 显示内连接 select * from A inner join B on 条件 (inner可以省略) 显示连

QBC查询、离线条件查询(DetachedCriteric)和分页查询模版

一.QBC检索步骤 QBC检索步骤: 1.调用Session的createCriteria()方法创建一个Criteria对象. 2.设定查询条件.Expression类提供了一系列用于设定查询条件的静态方法, 这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件. Criteria的add()方法用于加入查询条件. 3.调用Criteria的list()方法执行查询语句.该方法返回List类型的查询结果,在 List集合中存放了符合查询条件的持久化对象. 比较运

T-SQL查询语句 第二部分 (多表查询)

T-SQL查询语句大总结 防伪码:有志者事竟成,破釜沉舟,百二秦关终属楚 案例六:表如下图所示 在数据库中显示为: 实验需求: 1.两个表查询 select 学生表.姓名,学生表1.电话,学生表1.家庭住址 from 学生表,学生表1 where 学生表.学生id=学生表1.学生id 2.三个表的查询 select 学生表.姓名,课程表.课程名,成绩表.分数 from 学生表,课程表,成绩表 where 学生表.学生id=成绩表.学生id AND 成绩表.课程ID=课程表.课程ID 3.合并两个

mysql查询语句 和 多表关联查询 以及 子查询

原文地址: http://blog.csdn.net/github_37767025/article/details/67636061 1.查询一张表: select * from 表名: 2.查询指定字段:select 字段1,字段2,字段3-.from 表名: 3.where条件查询:select 字段1,字段2,字段3 frome 表名 where 条件表达式: 例:select * from t_studect where id=1; select * from t_student wh

SQL带条件,联合,分页查询语句

alter PROCEDURE Term4GetPagedData@pageIndex int = 1,--页码@pageSize int =10,--页容量@sMid int,@rowCount float output,--输出 总行数@pageCount float output--输出 总页数ASBEGINselect @rowCount = COUNT(sId) from Strategy where [email protected] --求总行数set @pageCount= CE

SQL判断语句用法和多表查询

1.格式化时间sql语句 本例中本人随便做了两张表,和实际不是很相符,只是想说明sql语句的写法. 例1表格式如下: 需求:查询出本表,但需要使time字段的时间格式为yyyy-MM-dd,比如:2013-08-13 sql写法: SELECT u.id,u.userId,u.timeType,DATE_FORMAT(time,'%Y-%m-%d') AS time,secondId FROM `user` u 运行结果: 2.多表查询(三表查询) 例二三表结构如下: 需求:查询出主表,要求在主

DML语句(八) -- 分页查询

一.应用场景 当要查询的条目数太多,一页显示不全 二.语法 SELECT 查询列表 FROM 表 LIMIT [offset,]size 注意: offset 代表的是起始的条目索引,默认从0开始 size 代表的是显示的条目数 公式: 假如要显示的页数为 page,每一页条目数为 size SELECT 查询列表 FROM 表 LIMIT (page - 1) * size,size 原文地址:https://www.cnblogs.com/xifengbuqi/p/9215669.html

sql 多条件查询 拼接字符串 改成 普通查询格式

set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROC [dbo].[usp_SRV_CheckServiceDemandOrder] @AInsNO NVARCHAR(50) =null,--必填 @ACompanyName NVARCHAR(50) = null,--必填 @ADepartmentName NVARCHAR(50) = null, @AName NVARCHAR(50) = null, --必填 @ApplicantI