数据库复杂sql如何编写入手

news2024/12/25 1:00:45

前言:说到数据库我想大家都不陌生,对主流的数据库都会基本使用,但是要写好sql完成复杂的sql编写是需要对数据库原理,sql脚本语法有一定的了解的,但是对于开发人员来说,平常都是在curd写一些业务代码,数据库接触的也不是那么复杂,对于复杂的业务场景,面对sql显然束手无策,对于后端开发人员来说去看一个几百行,几千行的sql实在头大,

出现这种sql的业务场景:

1,数据库多实例跨库查询,数据不同步,无法实现,主从同步实现。

2,数据库业务比较老,产品从多少年迭代过来的,发展成那种能不动就不动的业务代码或者sql.

3,业务本身就复杂,没有选择互联网产品,比如做一些数据分析,数据统计,你不采用大数据,一是成本高,企业成本也是有预算。

4,复杂的业务,比如金融,电商,需要做业务清算的都比较复杂。

5,多端的业务统计汇总,整个系统的业务统计。

以上几种情况都会出现业务负责,涉及到数据库统计计算的时候其实都是很复杂的,我们对于业务的发展没有好的规划和排期就会导致这样的问题发生,业务的复杂度不应该在数据存储上面,显然出现这样的情况只有一种原因,那就是设计不够量化,设计不够到位,没有一个闭环的业务,设计不够好,不能完全实现拓展和移植。

小杨今天就教大家如何写好一个复杂的sql,首先小杨数据库其实不算很精,但是对于一些复杂的sql我也是束手无策,但是呢你学习了程序,是有逻辑思想,所以你要通过排除和分析,对比,逆向思维去思考这个问题,分析这个问题的本质,当然了这个是身经百战才能有的能力,只有经过了大项目的压力,抗住了太多的压力才能不慌不忙去分析和解决问题。

今天就来分享一下小杨写这种复杂的sql如何写:

我们现在有个跨数据库实例的查询,多个库查询,我这边需要统计业务的答题做题数据,比如问卷星的题目和答案,我们通过送权益的方式兑换礼品,当然这是我们售后做满意度调查都会送成长值。当然我们的渠道有app,微信公众号,小程序,消息通知等。我们统计报表客户在哪个渠道答了多少题,分数是多少,答案是多少,我们需要改进的地方和成长值结算,这都是算成本。

显然这俩者完全没有任何关系,你在渠道答题和我问卷题目有啥关系,但是这是业务链路,比较长的链路了,我们可以答完题抽奖送积分。

我们通过任务触发去关联我们答卷的消息,把题目展示出来就行了。

LEFT JOIN (
	SELECT
		MAX( result ) result,
		CARE_TARGET_ID 
	FROM
		(
		SELECT
		CASE
				
			WHEN
				tc.SEND_RESULT LIKE CONCAT( '%', '"code":"200"', '%' ) THEN
					1 ELSE 0 
				END result,
	tt.CARE_TARGET_ID 
FROM
	database.tt_job tt
	LEFT JOIN database.tt_job_channel tc ON tc.`CARE_TARGET_ID` = tt.`CARE_TARGET_ID` 
	) 
GROUP BY
	CARE_TARGET_ID 
	) c1 ON c1.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r1.number,
		r1.`ANSWER_TEXT`,
		r1.`ID`,
		r1.`TITLE`,
		r1.`CARE_TARGET_ID`,
		r1.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type ='51291006'
		ORDER BY
			td.q_index ASC 
		) r1 
	WHERE
		r1.number = 1 
	) t1 ON t1.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r2.number,
		r2.`ANSWER_TEXT`,
		r2.`ID`,
		r2.`TITLE`,
		r2.`CARE_TARGET_ID`,
		r2.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null 
			AND tt.bill_type ='51291006' 
		ORDER BY
			td.q_index ASC 
		) r2 
	WHERE
		r2.number = 2 
	) t2 ON t2.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r3.number,
		r3.`ANSWER_TEXT`,
		r3.`ID`,
		r3.`TITLE`,
		r3.`CARE_TARGET_ID`,
		r3.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type= '51291006'
		ORDER BY
			td.q_index ASC 
		) r3 
	WHERE
		r3.number = 3 
	) t3 ON t3.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r4.number,
		r4.`ANSWER_TEXT`,
		r4.`ID`,
		r4.`TITLE`,
		r4.`CARE_TARGET_ID`,
		r4.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type = '51291006' 
		ORDER BY
			td.q_index ASC 
		) r4 
	WHERE
		r4.number = 4 
	) t4 ON t4.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r5.number,
		r5.`ANSWER_TEXT`,
		r5.`ID`,
		r5.`TITLE`,
		r5.`CARE_TARGET_ID`,
		r5.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type = '51291006'  
		ORDER BY
			td.q_index ASC 
		) r5 
	WHERE
		r5.number = 5 
	) t5 ON t5.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r6.number,
		r6.`ANSWER_TEXT`,
		r6.`ID`,
		r6.`TITLE`,
		r6.`CARE_TARGET_ID`,
		r6.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type  ='51291006' 
		ORDER BY
			td.q_index ASC 
		) r6 
	WHERE
		r6.number = 6 
	) t6 ON t6.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r7.number,
		r7.`ANSWER_TEXT`,
		r7.`ID`,
		r7.`TITLE`,
		r7.`CARE_TARGET_ID`,
		r7.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type ='51291006'
		ORDER BY
			td.q_index ASC 
		) r7 
	WHERE
		r7.number = 7 
	) t7 ON t7.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r8.number,
		r8.`ANSWER_TEXT`,
		r8.`ID`,
		r8.`TITLE`,
		r8.`CARE_TARGET_ID`,
		r8.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type ='51291006' 
		ORDER BY
			td.q_index ASC 
		) r8 
	WHERE
		r8.number = 8 
	) t8 ON t8.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r9.number,
		r9.`ANSWER_TEXT`,
		r9.`ID`,
		r9.`TITLE`,
		r9.`CARE_TARGET_ID`,
		r9.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null
			AND tt.bill_type = '51291006' 
		ORDER BY
			td.q_index ASC 
		) r9 
	WHERE
		r9.number = 9 
	) t9 ON t9.CARE_TARGET_ID = t.`CARE_TARGET_ID`
	LEFT JOIN (
	SELECT
		r10.number,
		r10.`ANSWER_TEXT`,
		r10.`ID`,
		r10.`TITLE`,
		r10.`CARE_TARGET_ID`,
		r10.`persion_id` 
	FROM
		(
		SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text !=null
			AND tt.bill_type = '51291006'
		ORDER BY
			td.q_index ASC 
		) r10 
	WHERE
		r10.number = 10 
	) t10 ON t10.CARE_TARGET_ID = t.`CARE_TARGET_ID` 
	AND t.bill_type = '51291006' 
WHERE
	1 = 1 
	AND p.care_type_code = '70851005' 

 扎眼一看这个sql特别长是不是,这只是一部分我不全部展示了,通过分析10个子查询,对应的题目和答案通过函数编号去标记题目信息。

 分层查询,嵌套:

第一层:

	SELECT
			td.`TITLE`,
			ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,
			td.`ANSWER_TEXT`,
			td.`ID`,
			tt.`CARE_TARGET_ID`,
			tp.`persion_id` 
		FROM
			database.tt_job tt
			LEFT JOIN database.tc_answer tp ON tp.`persion_id` = tt.`ANSWER_ID`
			LEFT JOIN database.tc_answer_detail td ON td.person_id = tp.id 
		WHERE
			td.title != '题目' 
			AND td.answer_text != null 
			AND tt.bill_type = '51291006'
		ORDER BY
			td.q_index ASC 

ROW_NUMBER ( ) over ( PARTITION BY tp.`PERSION_ID` ORDER BY td.q_index ) AS number,

函数根据id分组且下标排序,然后获取到 id排序取指定数据的编号把数据返回

第二层:

SELECT
		r1.number,
		r1.`ANSWER_TEXT`,
		r1.`ID`,
		r1.`TITLE`,
		r1.`CARE_TARGET_ID`,
		r1.`persion_id` 
	FROM
		(

) r1 WHERE
		r1.number = 1

 第二层数据就简单了根据第一层的数据返回的赋值到外层了,显然我们获取指定r1,number的那条数据对不对

第三层:

LEFT JOIN (
) t2 ON t2.CARE_TARGET_ID = t.`CARE_TARGET_ID`

第三层无非就是把第二层的统计数据 返回到外层然后查询主键关联到外面的表,从而完成了一次嵌套子查询。显然这个sql也没有那么难啊。

当然还有4层5层,78层也很正常。

编写复杂sql的内功心法:

1,拆解复杂sql的逻辑业务,从内到外,这点和程序不一样,程序是从上往下,而sql是从内到外。

2,每一层查询分析,直到外层,把数据反出去。

3,合理运用mysql内置函数,帮助我们分析统计。

4,以功能实现为主,优化性能我们可以后期优化。

 ————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)

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

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

相关文章

Flutter 中使用 OpenAI GPT-3 进行语义化处理

Flutter 中使用 OpenAI GPT-3 进行语义化处理 前言 最近 openai 的 ChatGPT 火了,然后我也想着用它来做点什么,于是就写了个 调用 openai api 语言执行工具,跑个测试,以后再有功能也可以在这个程序上面试验。 copilot 也是用的 op…

m基于FPGA的64QAM调制解调、载波同步verilog实现

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 64QAM(正交幅度调制),在使用同轴电缆的网络中,这种数字频率调制技术通常用于发送下行链路数据。64QAM在6mhz信道中,64QAM的传输速率非常…

Qt编写视频监控系统(移动侦测/遮挡报警/区域入侵/越界侦测/报警输入输出等)

一、前言 得益于标准的onvif协议,各大监控厂商的设备都会支持onvif协议,在onvif协议中就包括了事件订阅机制,通过这个机制,可以拿到各种报警事件,比如移动侦测/遮挡报警/区域入侵/越界侦测/报警输入输出等&#xff0c…

深度学习-环境搭建(安装Pytorch)

文章目录前言一、安装Anaconda二、查看电脑显卡支持的CUDA版本三、更新CUDA版本四、创建并激活Anaconda虚拟环境需要创建虚拟环境而最好不在base下载的原因五、安装pytorchPS:注意事项六、下载其他库七、检查安装结果总结前言 入门深度学习过程中,我决定…

[附源码]JAVA毕业设计鞋店销售管理(系统+LW)

[附源码]JAVA毕业设计鞋店销售管理(系统LW) 项目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术&…

都在说软件测试真的干不到35岁,那咋办呢...我都36了...

作为一个已经36岁但仍奋战在测试一线的老测试员,被人无数次问到这个问题,也回答过无数次,刚看到 程序员真的干到35岁就干不动了吗 想到,在测试行业,也有很多年轻人在焦虑这个问题。现在小编就从管理、技术、思维、体力…

Pytho——naiohttp的简单使用

1.aiohttp的简单使用(配合asyncio模块) import asyncio,aiohttpasync def fetch_async(url):print(url)async with aiohttp.request("GET",url) as r:reponse await r.text(encoding"utf-8")  #或者直接await r.read()不编码,直接读取&…

我不谈ChatGPT

(1)数据有两个未经证实的传闻:1、客服问答:80%用户问的问题都是那20%常见问题,但是就是这样,占用了客服人员80%的工作量和工作时间2、资讯搜索:谷歌一位员工说,在互联网上&#xff0…

Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)

​​​​​​​ Spring Cloud Alibaba简介 什么是Spring Cloud Alibaba Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。 此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 为…

OSI七层模型中各层网络协议

应用层: (典型设备:应用程序,如FTP,SMTP ,HTTP) DHCP(Dynamic Host Configuration Protocol)动态主机分配协议,使用 UDP 协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配 IP 地址&#xff0c…

spring——Spring 注入内部Bean——setter 方式注入内部 Bean

我们将定义在 <bean> 元素的 <property> 或 <constructor-arg> 元素内部的 Bean&#xff0c;称为“内部 Bean”。 项目依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org…

交战“低代码”,云大厂跑马圈地

者 关注 2022年末,云大厂阿里、腾讯、华为(ATH)开始了新一轮的跑马圈地。 这一次交战的战场,是低代码。 11月18日,华为AppCube全线产品全面升级,在低代码、零代码、数据看板三个方面,升级优化;11月13日,腾讯升级了云开发开发者工具“微搭”,目前已服务开发者数300万…

疫情期间,家中常备药物有哪些?这份清单请收好

【防疫科普】疫情期间&#xff0c;家中常备药物有哪些&#xff1f;这份清单请收好 为加强防疫知识科普&#xff0c;提振群众战“疫”必胜信心&#xff0c;疫情期间&#xff0c;我们将持续向广大市民朋友传递科学健康科普知识、防疫提醒、自我防护注意事项、疫情期间心理疏导等相…

Python融于ASP框架

一、ASP的平反 想到ASP 很多人会说 “asp语言很蛋疼&#xff0c;不能面向对象&#xff0c;功能单一&#xff0c;很多东西实现不了” 等等诸如此类。 以上说法都是错误的&#xff0c;其一ASp不是一种语言是 微软用来代替CGI的一种web框架&#xff0c;只不过我们一直被扭曲在 vbs…

计算机毕业设计php_thinkphp_vue的校园论坛网站

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHP&#xff1a;vue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 在各学校的校园论坛中,交流是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流…

Python 数据库开发实战 - Redis命令行客户端与图形客户端的简单使用

上一章节我们已经启动了 redis 服务器&#xff0c;在这一章节我们就爱你过来学习 redis命令行客户端与图形客户端的简单使用&#xff0c;以及 redis 的 一些关键参数。 Redis 命令行客户端 - redis-cli redis-cli 是 Redis 自带的 命令行终端界面&#xff0c;一个简单的程序&…

【Redis】Redis 分布式锁误删问题

本文主要介绍 Redis 分布式锁误删问题的解决 场景一 1. 问题的产生情况一 因为业务阻塞&#xff0c;导致别人的锁被误删 2. 解决思路 获取锁的时候存入标识&#xff0c;释放锁的时候判断标识是否一致&#xff0c;一致可以释放锁&#xff0c;不一致不释放锁。 3. 解决代码 …

今年,我只赚了一点点

大家好&#xff0c;我是 Jack。 之前一直有小伙伴问我&#xff0c;有没有免费的股票信息查询的 API 接口&#xff1f; 我看了一圈&#xff0c;很多免费的 API 接口都年久失修&#xff0c;失效了。 那好吧&#xff0c;咱自己写一个。 想要玩量化交易&#xff0c;第一步&…

015 | 乡村振兴背景下田园综合体建设对农户生计的影响 | 大学生创新训练项目申请书 | 极致技术工厂

研究目的 本项目旨在研究xx市xx区田园综合体建设对农户生计的影响。以农户生计资本和生计恢复力为切入点&#xff0c;以塘坝镇、崇龛镇、太安镇等六个地级镇田园综合体建设前后作对比&#xff0c;研究其田园综合体建设对农户生计的影响&#xff0c;以期找到乡村振兴背景下田园综…

前端岗位编写代码注意规范

&#x1f525;&#x1f525;&#x1f525;关注前端小王hs&#x1f525;&#x1f525;&#x1f525; &#x1f525;&#x1f525;&#x1f525;加底部微信&#x1f525;&#x1f525;&#x1f525; &#x1f525;&#x1f525;&#x1f525;学习指导/前端练手项目推荐/毕设选题/…