SqlSugar分组查询
一、分组查询和使用
1.1 语法
只有在聚合对象需要筛选的时候才会用到Having,一般分组查询用不到可以去掉
var list = db.Queryable<Student>() .GroupBy(it => new { it.Id, it.Name }) //可以多字段 .Where(it=>it.Id>0)//普通过滤 //.Having(it => SqlFunc.AggregateAvg(it.Id) > 0)//聚合函数过滤 .Select(it => new { idAvg = SqlFunc.AggregateAvg(it.Id??0), count = SqlFunc.AggregateCount(it.Id), name = it.Name }) .ToList(); // SELECT // AVG([Id]) AS[idAvg], // [Name] AS[name] // // FROM[Student] GROUP BY[Name],[Id] Where Id > 0 //Count用法//SqlFunc.AggregateCount(it.Id)//单个字段用法 (多个单个也能叠加) .GroupBy(it =>SqlFunc.SubString(it.Name,0,1)) .GroupBy(it =>it.Id) //新版本支持了分组带函数 .GroupBy(it=>new { it.Id, name= SqlFunc.ToString(it.Name) } |
分组查询可以 进行汇总查询 、平均值、最大、最小等操作
1.2 去null(isnull或ifnull)
库中存在null如果不处理那么avg和sum将查询不了数据
SqlFunc.AggregateSumNoNull(it.num) //等于 sum(isnull(num,0))//5.1.4.108-preview31+SqlFunc.AggregateAvgNoNull(it.num) //等于 avg(isnull(num,0))//nullable类型也可以用??去除nullSqlFunc.AggregateSum(it.num??0)// avg(isnull(num,0)) //原始用法SqlFunc.AggregateSum(SqlFunc.Isnull(it.num,0))// avg(isnull(num,0)) |
1.3 排序统计列
var list = db.Queryable<Student>() .GroupBy(it => new { it.Id, it.Name }) .Where(it=>it.Id>0) .Select(it => new { idAvg = SqlFunc.AggregateAvg(it.Id??0), count = SqlFunc.AggregateCount(it.Id), name = it.Name }) .MergeTable()//需要加MergeTable才能排序统计过的列 .OrderBy(it=>it.count) .ToList(); |
二、Distinct使用
一般用来指定字段去重复,查询不重复的值,去重字段
var list = db.Queryable<Student>().Distinct().Select(it => new { it.Name }).ToList();//SELECT DISTINCT [Name] AS [Name] FROM [STudent] |
注意:升级较新版本兼容了rownumber冲突
三、分组获取第一条(或几条)
3.1 所有数据库通用写法
var list=db.Queryable<Order>() .GroupBy(it => it.Name)//MergeTable之前不要有OrderBy .Select(it => new { name = it.Name, id = SqlFunc.AggregateMax(it.Id) }) .MergeTable() .LeftJoin<Order>((a, b) => a.id == b.Id) //OrderBy((a,b)=a.Id) .Select((a, b) => b).ToList();// SELECT [b].* // FROM // (SELECT*FROM(SELECT [Name]AS[name],MAX([Id]) AS [id] FROM [Order] GROUP BY [Name]) MergeTable )[a]// Left JOIN // [Order] [b] ON ( [a].[id] = [b].[Id] ) |
该写法只能支持获取1条,如果想分组获取1条以上看 标题2
3.2. 开窗函数语法实现(较多库支持)
新版本才支持 5.1.1
支持数据库:SqlServer、MySql8.0+、Oracle 、PgSql、达梦、金仓 等数据库支持
说明: partition by name 就等于 group by name
var test48 = db.Queryable<Order>().Select(it => new { index2 = SqlFunc.RowNumber(it.Id,it.Name),//order by id partition by name //多字段排序 order by id asc ,name desc //SqlFunc.RowNumber($"{it.Id} asc ,{it.Name} desc ",$"{it.Name}") price=it.Price, date=it.CreateTime }) .MergeTable()//将结果合并成一个表 .Where(it=>it.index2==1) //相同的name只取一条记录 //前20条用Where(it=>it.index2=<=20) .ToList(); //SELECT * FROM // (SELECT //row_number() over( partition by [Name] order by [Id]) AS [index2], //[Price] AS [price] , //[CreateTime] AS [date] FROM [Order] // ) MergeTable WHERE ( [index2] = 1 )//多个字段 5.1.2-preview01SqlFunc.RowNumber($"{it.Id} asc ,{it.Name} desc " , $"{it.Id},{it.Name}")//partition by [id],[Name] order by [Id] asc,[name] desc |
3.3 个别数据库写法
1.个别库独有实现像Oracle 、SqlServer 语法糖db.Queryable<Order>().Take(1).PartitionBy(it=>it.Name).ToList()db.Queryable<Order>().OrderBy(it=>it.id,OrderByType.Desc).Take(1).PartitionBy(it=>it.Name).ToList() |
四、特殊日期分组
例子1 : 年月分好组简写
var students = db.Queryable<Order>() .GroupBy(it=>it.CreateTime.ToString("yyyy-MM")) .Select(it=>new { Time=it.CreateTime.ToString("yyyy-MM"), Count=SqlFunc.AggregateCount(it.name) }) //如果想在后面OrderBy //.MergeTable().OrderBy(it=>it.Count) .ToList(); |
例子2: 根据年月日进行分组
var getOrderBy = db.Queryable<Order>().Select(it=>new { Id=it.Id, Name=it.Name,//这儿不能写聚合函数,因没分组 CreateTime=it.CreateTime.Date//只取日期 }) .MergeTable()//将查询结果转成一个表 .GroupBy(it=>it.CreateTime) .Select(it=>new { id =SqlFunc.AggregateMax(it.Id),crate=it.CreateTime }) .ToList(); |
例子3:使用SQL语句分组
.GroupBy(it => SqlFunc.MappingColumn(default(string), " CONVERT(varchar(10),t.F_OutTime, 120)"))//生成的Sql如下//GROUPBY CONVERT(varchar(10),t.F_OutTime, 120) |
五、Count(distinct 字段)
db.Queryable<Order>().Select(it=>SqlFunc.AggregateDistinctCount(it.Id)).ToList()//最新版本支持db.Queryable<Order>().Select<int>("count(distinct id)").ToList(); |
六、强制不参数化
语法更新:
//新语法 5.1.4.64SqlFunc.MappingColumn<string>("'a'") //生成的Sql是 'a' ,不会是参数化对象SqlFunc.MappingColumn<int>("1") //生成的Sql是1//老版本语法SqlFunc.MappingColumn(default(string),"'a'")SqlFunc.MappingColumn(default(int),"1") |
一般解决GroupBy参数名不同引起的分组失败
例如:Group里面是参数@p1=1 Select中是参数 @p2 =1 ,只因参数名不同引起了分组失败
//改之前var list = db.Queryable<Order>() .GroupBy(it =>it.Name.Substring(0,1)) .Select(it => new { name=it.Name.Substring(0,1)) }).First();//改之后var list = db.Queryable<Order>() .GroupBy(it => it.Name.Substring( SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("1"))) .Select(it => new { name=it.Name.Substring( SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("1")) }).First();//这样生成的Sql就不会有参数化对象了//SELECT SUBSTRING(`Name`,1 + 0,1) AS `name` FROM `Order` // GROUP BY SUBSTRING(`Name`,1 + 0,1) LIMIT 0,1 |
七、联表中GroupBy用法
db.Queryable<Student>() .LeftJoin<Book>((it,b)=>it.id==b.studentid) .GroupBy((it,b)=> new { it.Id, it.Name }) //可以多字段 .Having((it,b)=> SqlFunc.AggregateAvg(it.Id) > 0)//不是聚合函数用Where就可以了 .Select((it,b)=> new {idAvg=SqlFunc.AggregateAvg(it.Id),name=it.Name})//Select写最后 .ToList(); //GroupBy用到b表那就应该写成 (it,b)=>new {} //没用到b表可以写成这样 it=>new{} |
联表查询用法:https://www.donet5.com/Home/Doc?typeId=1185
八、分组取ID+集合的方式(ef类似)
请升级到 5.1.4.66
//List<T>集合 var list = db.Queryable<Order>() .Where(it=>it.Id>0) .GroupBy(it=>it.CustomId)//根据CustomId分组 .Select(it => new { cusid=it.CustomId, list=SqlFunc.Subqueryable<Order>().Where(s=>s.CustomId==it.CustomId).ToList() }).ToList(); //List<string>集合 var list = db.Queryable<Order>() .Where(it=>it.Id>0) .GroupBy(it=>it.CustomId)//根据CustomId分组 .Select(it => new { cusid=it.CustomId, ids=SqlFunc.Subqueryable<Order>().Where(s=>s.CustomId==it.CustomId).ToList(s=>s.Id) }).ToList(); |
九、所有开窗口函数
是group的高级应用 ,他不依赖group可以分组,并且可以多个使用而不需写group
count = SqlFunc.RowCount(),// count (1) over() max= SqlFunc.RowMax(it.num??0),// max(isnull(num,0)) over() min= SqlFunc.RowMin(it.num??0),// min(isnull(num,0)) over() avg= SqlFunc.RowAvg(it.num??0),// avg(isnull(num,0)) over() index = SqlFunc.RowNumber(it.Id), // row_number() over( order by a.`Id`) index = SqlFunc.RowNumber(it.Id,it.Name)// row_number() over( partition by name order by a.`Id`) index = SqlFunc.RowNumber(SqlFunc.Desc(it.Id),it.Name)// row_number() over( partition by name order by a.`Id` desc) //多字段看3.1 |
十、Count加条件
通过sum加三元实现Count加条件统计,Sum(1)等于同Count, 只把不想的改成0这样Sum就是统计的想要的
var list = db.Queryable<Student>() .GroupBy(it => new { it.Name }) .Select(it => new { count= SqlFunc.AggregateSum(it.Id>10?1:0), }) .ToList(); |
十一、不分组使用Count
更多看标题9
count = SqlFunc.RowCount(),// count (1) over() |
SqlSugar分组查询的更多相关文章
- MySQL时间分组查询
表TESTER 字段:id -- INT date -- TIMESTAMP 1.如何按年.月.日分组查询? select DATE_FORMAT(date,'%Y-%m-%d') time, ...
- 关系数据库SQL之基本数据查询:子查询、分组查询、模糊查询
前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[ ...
- Hibernate 分组查询 子查询 原生SQL
分组查询: 使用group by关键字对数据分组,使用having关键字对分组数据设定约束条件,从而完成对数据分组和统计 1.1 聚合函数:常被用来实现数据统计功能 ① count() 统计记录条数 ...
- mysql 分组查询问题 group_concat
这几天在做购物车的时候.购物车内的商品为一个商品占一行,结果再从数据库读出的时候,没有分组,而是循环所有的内容出来,然后进行判断.如果一样的话就把他保存到一个变量中.但是自己逻辑没搞清楚.一直出bug ...
- mongodb 分组查询
数据的保存 include_once 'mDB.class.php'; $m=new mDB(); $m->setDB('mydb'); // $m->save('stu',['dept' ...
- 08章 分组查询、子查询、原生SQL
一.分组查询 使用group by关键字对数据分组,使用having关键字对分组数据设定约束条件,从而完成对数据分组和统计 1.1 聚合函数:常被用来实现数据统计功能 ① count() 统计记录条数 ...
- Mongodb for C# 分组查询
#region 排序获取集合 static List<BsonDocument> GetPagerWithGroup(string connectionString, string dat ...
- SQL分组查询group by
注意:select 后的字段,必须要么包含在group by中,要么包含在having 后的聚合函数里. 1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用 group ...
- SQL group by分组查询(转)
本文导读:在实际SQL应用中,经常需要进行分组聚合,即将查询对象按一定条件分组,然后对每一个组进行聚合分析.创建分组是通过GROUP BY子句实现的.与WHERE子句不同,GROUP BY子句用于归纳 ...
- mongodb使用mongoose分组查询
一个分组查询的例子: model.aggregate([{$match: ops}, {$unwind: '$details'}, {$sort: {create_at: -1}}, { $group ...
随机推荐
- JPA 表名大小写问题
JPA 默认会将实体中的 TABLE_NAME 转成小写如 @Entity @Table(name = "EMPLOYEE") public class Employee { @I ...
- NOKOV度量动作捕捉协助完成无人机室内定位研究
随着工业发展.技术进步,无人机的使用在各行各业愈发普遍,开始出现无人机飞行送外卖.智能无人机自主巡检等多方面应用.在这一过程中,无人机飞行定位就成为了重中之重. 西北工业大学无人机特种技术国防科技重点 ...
- 【JAVA基础】Swagger使用
Swagger使用 刷新权限 自定标签名称
- Wiindows下更改CMake编译器为MinGW
个人环境 MinGW:使用 QT6 install 的 mingw1120_64. CMake:使用 QT6 install 的 CMake 3.24.2. 第一次编译时,默认生成VS的工程文件,为了 ...
- 【C++第三方库】Windows下编译和使用 WebSocket++/WebSocketpp
应用场景: 使用C++开发一个支持websocket协议的服务进程,可与HTML5(浏览器js文件)通信.来实现替换基于firebreath框架的跨浏览器插件开发. 当前,讲述websocketpp开 ...
- #1241: Oil Deposits(八向搜索 + 并查集)
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- 【网摘】SQL练习题
原文链接:Here
- 【每日一题】35. [CQOI2009]中位数图 (前缀和,贡献值计算)
补题链接:Here 算法涉及:前缀和,贡献值计算 经典中位数计数问题,记得以前百度之星也出过类似的题,这道题有一个限定范围是要奇数区间的 我们很容易想到,奇数下标到偶数下标或者偶数下标到奇数下标的长度 ...
- Vue3 Diff算法之最长递增子序列,学不会来砍我!
专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位ITer关注点赞收藏 Vue2 Diff算法可以参考[Vue2.x源码系列08]Diff算法 ...
- poj 3268 最短路
***题意:在x这个点有个聚会,其他的点要到x这个点,然后再会自己原始的点,求一来一回最大的那个距离 做法:两边dijstra算法,因为是单向图,要注意更新顺序*** #include<iost ...