sql 分组讨论,二级分组(非2个字段分组),使用 窗口函数和普通分组实现

1. 二级分组需求

  • 先按照一个字段分组,在按照 第二个字段分组。
  • 之后,如果 这个 二级分组中的数据,是 > 1条的。就筛选出来。

比如:

  • 先按照 站点分组,再按照 设备分组,

  • 即:如果站点上配置了2个设备。就筛选出来。

    • 然后:这2个设备 都必须是屏幕
  • 查出配置了2个设备的站点

SELECTe2.station,e2.device 
FROMesb_config e2 
GROUP BYe2.station 
HAVINGcount( 1 ) > 1
  • 要求 这两个设备都是屏幕,参考SQL和思路1

错误写法

	SELECTe2.station,e2.device FROMesb_config e2GROUP BY e2.station,e2.device HAVING count(*) > 1 -- 这样是错误的,这样是根据2个字段 分组。结果不会存在 > 1的情况
GROUP BY e2.station HAVING count(e2.device) > 1
-- 这样写无异议 等于 HAVING count(e2.station) > 1,也是错误的GROUP BY e2.station
-- 核心是:这样查询后,会随机带出 一个device。
-- 所以哪怕 外层在套一个分组(因为经过一层后,已经选出了一个device了),也是错的。

问题从头整理

表结构和数据

CREATE TABLE `user` (`id` int NOT NULL,`username` varchar(22) DEFAULT NULL,`info` varchar(22) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;1	zhangsan	1
2	lisi	22
3	lisi	33-- 我们要查出lisi
-- 先按照姓名分组,在按照 info 分组。
-- info中的 数据>1,就查询出来
collate/kəˈleɪt/
vt.
核对,校对;校勘

按照username分组

SELECT * 
FROM `user`
GROUP BY username-- 按照username分组后,lisi会随机选一条(第一条)
1	zhangsan	1
2	lisi	22

加入扰乱数据

INSERT INTO `user`(`id`, `username`, `info`) VALUES (4, 'zhangsan', '1');
-- 此时数据的数据为
1	zhangsan	1
2	lisi	22
3	lisi	33
4	zhangsan	1
  • 加条件
SELECT * 
FROM `user`
GROUP BY username
HAVING count(username) > 1-- 结果为:此时zhangsan是info相同的,不应该出现。count(1),或 count(其他值) 结果都一样
1	zhangsan	1
2	lisi	22

两个字段分组 加条件

  • 分3组
-- 此时数据的数据为
1	zhangsan	1
2	lisi	22
3	lisi	33
4	zhangsan	1SELECT * 
FROM `user`
GROUP BY username,info-- 根据 两个字段分组,后变成3组
1	zhangsan	1
2	lisi	22
3	lisi	33
  • 此时分组中的数据 > 1的为 zhangsan
SELECT * 
FROM `user`
GROUP BY username,info
HAVING count(1) > 1-- 结果
1	zhangsan	1

2. 业务

真实的问题

  • 业务要求了,必须是 一个站点绑定两个设备都是屏幕,才查询出来。

  • 无用的SQL保存,验证这个真实的设备是不是 屏幕

SELECT* 
FROMdevice d,device_type dt 
WHEREd.deviceType = dt.id AND d.id = 'e696cfeeb4568ccfcda0ae6787388760' AND dt.attribute = '屏幕'

先 where,在 having

  • where语句的执行顺序先于group by,group by语句的执行顺序先于having
    • having 子句中的每一个元素也必须出现在select列表中,
    • having语句可以使用聚合函数。

SQL和实现思路1 窗口函数

SELECT* 
FROM(SELECTe2.station,ROW_NUMBER() OVER ( PARTITION BY e2.station ) row_num FROMesb_config e2,device d,device_type dt WHEREd.deviceType = dt.id AND dt.attribute = '屏幕' AND e2.device = d.id ) t1 
WHEREt1.row_num > 1-- 窗口函数 再次赋值
SELECT* 
FROM(SELECTe2.station,ROW_NUMBER() OVER ( PARTITION BY e2.station ) row_num FROMesb_config e2) t1
WHEREt1.row_num > 1

SQL和实现思路2 分组

  • 查出 站点配置了 多个设备的 站点
SELECTe2.station,e2.device 
FROMesb_config e2 
GROUP BYe2.station 
HAVINGcount( 1 ) > 1
  • 这多个设备 必须是屏幕,才能查出来。
    • 对站点进行了分组:
SELECTe2.station,e2.device 
FROMesb_config e2,device d,device_type dt 
WHEREd.deviceType = dt.id AND dt.attribute = '屏幕' AND e2.device = d.id
-- 上面SQL 查出了配置表中,所有为屏幕的 设备和站点
-- 此时一个站点 如果配置了 多个屏幕,这个站点就会展示出多条-- 然后在筛选一下,站点>1 的
GROUP BYe2.station 
HAVINGcount( 1 ) > 1

扩展怎么显示 一个站点,显示2次呢

  • 思路1再关联原表

  • 使用这个逻辑,有一个问题。怎么显示 一个站点,显示2次呢(设备不同的时候)

    • 很简单,只需要在 外层关联一个 表即可(因为这个表 本来就是这种逻辑,一个站点,显示2次)
SELECT * from esb_config e1, (SELECTe2.station FROMesb_config e2,device d,device_type dt WHEREd.deviceType = dt.id AND dt.attribute = '屏幕' AND e2.device = d.id GROUP BYe2.station HAVINGcount( 1 ) > 1
) t1
WHERE e1.station = t1.station-- 核心是这样的结果
SELECT * from esb_config e1, (SELECTe2.station -- 这里,e2.device 取了没用,只是会筛选第一个 FROMesb_config e2GROUP BYe2.station HAVINGcount( e2.station  ) > 1) t1
WHERE e1.station = t1.station-- 那这个结果加上限制对不对呢?不对的,为啥不对,这里不懂。
-- AND dt.attribute = '屏幕' 

SQL和思路3 错误的

  • 把一级分组,查询出来

  • 把二级分组,查询出来

  • 如果 一级分组 和 二级分组,关联上就展示

  • 这样 查出的数据 只查出了一条(也是上面的 数据之一)

SELECT* 
FROM( SELECT * FROM (SELECTe2.station,e2.deviceFROMesb_config e2,device d,device_type dt WHEREe2.device = d.id AND d.deviceType = dt.id AND dt.attribute = '屏幕') t2GROUP BY t2.station HAVING count(t2.station) > 1 ) t1,(SELECT * FROM (SELECTe2.station,e2.device FROMesb_config e2,device d,device_type dt WHEREe2.device = d.id AND d.deviceType = dt.id AND dt.attribute = '屏幕') t2GROUP BY t2.device HAVING count(t2.device) > 1 ) t3WHEREt1.station = t3.station and t1.device = t3.device

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio构建SpringSecurity权限框架

1.Cloud Studio(云端 IDE)简介 Cloud Studio 是基于浏览器的集成式开发环境(IDE),为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装,随时随地打开浏览器就能在线编程。 Clou…

Spring 知识点

Spring 1.1 Spring 简介 1.1.1 Spring 概念 Spring是一个轻量级Java开发框架,最早有Rod Johnson创建为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。使现有的技术更加容易使…

Linux下进程的特点与环境变量

目录 进程的特点 进程特点的介绍 进程时如何实现并发性的 进程间如何切换 概念铺设 PC指针 上下文 环境变量 PATH 修改PATH HOME SHELL env 命令行参数 什么是命令行参数? 打印命令行参数 通过函数获得环境变量 getenv 命令行参数 env 修改环境变…

Ajax_3 Ajax原理+ (XMLHttpRequest + Promise )+ 封装一个axios插件库,实现功能。

Ajax_3 Ajax原理 01-Ajax原理-XMLHttpRequest 使用XMLHttpRequest 步骤: 创建XMLHttpRequest对象配置请求方法请求url网址监听loadend事件,接受响应结果发起请求 需求:使用XMLHttpRequest对象与服务器通信 代码示例 // 1. 创建 XMLHttpReq…

SpringBoot 项目使用 Redis 对用户 IP 进行接口限流

一、思路 使用接口限流的主要目的在于提高系统的稳定性,防止接口被恶意打击(短时间内大量请求)。 比如要求某接口在1分钟内请求次数不超过1000次,那么应该如何设计代码呢? 下面讲两种思路,如果想看代码可…

一分钟了解下Java追随和适应云原生的手段之Java Native Build(JNB)

文章首发地址 为了解决在云原生环境中,Java应用启动慢的问题,出现了很多派系,如拯救派,让应用在原有基础上启动更快(一般都是用资源换时间),还有就是革命派,Java向Golang学习&#x…

MySql用户管理、权限管理

用户管理 1. 查看系统用户(查询mysql系统数据库中的user表) select * from mysql.user; 2. 创建用户 CREATE USER 用户名主机名 identified by 密码 -- 创建用户zhonghua,只能在当前主句localhost访问,密码为123456 create user zhonghualocalhost i…

springCache-缓存

SpringCache 简介:是一个框架,实现了基于注解的缓存功能,底层可以切换不同的cache的实现,具体是通过CacheManager接口实现 使用springcache,根据实现的缓存技术,如使用的redis,需要导入redis的依赖包 基于map缓存 …

MySQL 查询语句大全

目录 基础查询 直接查询 AS起别名 去重(复)查询 条件查询 算术运算符查询 逻辑运算符查询 正则表达式查询⭐ 模糊查询 范围查询 是否非空判断查询 排序查询 限制查询(分页查询) 随机查询 分组查询 HAVING 高级查询…

EtherCAT转EtherCAT网关FX5U有EtherCAT功能吗两个ETHERCAT设备互联

1.1 产品功能 捷米JM-ECT-ECT是自主研发的一款ETHERCAT从站功能的通讯网关。该产品主要功能是将2个ETHERCAT网络连接起来。 本网关连接到ETHERCAT总线中做为从站使用。 1.2 技术参数 1.2.1 捷米JM-ECT-ECT技术参数 ● 网关做为ETHERCAT网络的从站,可以连接倍福、…

C++:子串计算

子串计算 题目描述 给出一个01字符串(长度不超过100),求其每一个子串出现的次数。 输入输出格式 输入描述: 输入包含多行,每行一个字符串。 输出描述: 对每个字符串,输出它所有出现次数在1次以上的子串和这个子串出…

小型双轮差速底盘机器人实现红外跟随功能

1. 功能说明 本文示例将实现R023样机小型双轮差速底盘跟随人移动的功能。在小型双轮差速底盘前方按下图所示安装3个 近红外传感器,制作一个红外线发射源,实现当红外发射源在机器人的检测范围内任意放置或移动时,机器人能追踪该发射源。 2. 电…

网络安全学习笔记——SalMap爆破添加快捷方式

SqlMap的使用 SqlMap是SQLMap注入的神器,但是SqlMap只能跑一些过滤不太严格的注入,也可以使用Python编写的脚本跑 SqlMap使用 本机先装好Python环境,打开sqlmap下的cmd,在cmd的对话框输入python sqlmap.py 启动SqlMap&#xff0…

抖音seo矩阵系统源码搭建开发详解

抖音SEO矩阵系统是一个用于提高抖音视频在搜索引擎排名的工具。如果你想开发自己的抖音SEO矩阵系统,以下是详细的步骤: 开发步骤详解: 确定你需要的功能和算法 抖音SEO矩阵系统包含很多功能,比如关键词研究、内容优化、链接建设、…

Qt中qmake、构建、运行、清理的区别

Qt 中默认的执行顺序:qmake--- 编译 --- 运行。 一、qmake qmake: 根据之前项目指南创建的项目文件 .pro,并且运行 qmake [qmake xx.pro]生成调试 [build-ttt-***-Debug] 或者发布 [build-ttt-***-Release] 目录(这个是影子构建…

PHP8的跳转语句-PHP8知识详解

如果循环条件满足的时候,则程序会一直执行下去。如果需要强制跳出循环,则需要使用跳转语句来完成。PHP8的跳转语句包括break语句、continue语句和goto语句。 1、break语句 break语句的作用是完全终止循环,包括while、do…while、for、switch…

6. CSS(三)

目录 一、盒子模型 (一)网页布局的本质 (二)盒子模型组成 (三)边框(border) (四)表格的细线边框 (五)内边距(padding…

[JavaScript游戏开发] 绘制Q版地图、键盘上下左右地图场景切换

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测 第四章 绘制Q版地图、键盘上下左右地图场景切换 文章目录 系列文章目录前言一、本章节…

【TypeScript】类型断言-类型的声明和转换(五)

【TypeScript】类型断言-类型的声明和转换(五) 【TypeScript】类型断言-类型的声明和转换(五)一、简介二、断言形式2.1 尖括号语法2.2 as形式 三、断言类型3.1 非空断言3.2 肯定断言-肯定化保证赋值3.3 将任何类型断言为any3.4 调…

LangChain与大模型的学习ing

大模型的菜鸟初学习 一、问题记录1、库的版本问题 二、实例记录1、公司名生成2、提示模板的使用3、LLM Chain4、LLMMemory5、聊天语言API 参考资料 一、问题记录 1、库的版本问题 openai.error.APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(ho…