zoukankan      html  css  js  c++  java
  • 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 profileid=@profileid and  storeId=@storeId 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(@"As*SELECTs+((?:((?>((?<depth>)|)(?<-depth>)|.?)*(?(depth)(?!)))|.)*?)(?<!,s+)FROM",
                RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
    
            public Regex RegexDistinct = new Regex(@"ADISTINCTs",
                RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
    
            public Regex RegexOrderBy =
                new Regex(
                    @"ORDERs+BYs+(?!.*?(?:)|s+)ASs)(?:((?>((?<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}
    LIMIT {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; }
        }
    }
  • 相关阅读:
    Codeforces Round #610 (Div. 2)C(贪心,思维)
    Educational Codeforces Round 80 (Rated for Div. 2)C(DP)
    BZOJ2190 仪仗队
    BZOJ3613 南园满地堆轻絮
    BZOJ1084 最大子矩阵
    BZOJ1036 树的统计Count
    BZOJ1452 Count
    BZOJ2242 计算器
    BZOJ2705 Longge的问题
    BZOJ1509 逃学的小孩
  • 原文地址:https://www.cnblogs.com/songshuai/p/5737379.html
Copyright © 2011-2022 走看看