0

0

积累一下SQL_MySQL

php中文网

php中文网

发布时间:2016-05-30 17:09:55

|

1188人浏览过

|

来源于php中文网

原创

动态SQL

 

她当时教我最厉害的一招利用SQL生成SQL最终执行查询,大致就是通过sys.table查出表名,生成SQL并合并,最后exec执行。感觉还是比较有用。假设数据库中有一堆命名规范且结构相似的表,要查出这批表的数据,就可以考虑一下用这样的方式

 

首先从把表名查出来

 

SELECT name FROM sys.tables WHERE name like '%表名的模式%' AND type= 'U'

 

上面的通配符什么的就不说了,接下来就是要把查询数据的SQL语句拼接出来了。原来还可以这样用,看来以前是没开窍或者是太老实了。

 

SELECT ' UNION SELECT * FROM '+ name FROM sys.tables WHERE name like '%表名的模式%' AND type='U'

 

这样查询出来的结果就是最终SQL的半成品。但上面我觉得尽量不要用*,这里有表的结构不一样,UNION就会出错了。接下来还需要经过组合和截取,这里就用到了两个函数,一个是 FOR XML PATH(''),另一个是stuff(),顺序是先让上面的结果合并成一个字符串,再去截取。SQL就成下面的样子

 

DECLARE @sql varchar(max)

 

SET @sql= SELECT ' UNION SELECT * FROM '+ name FROM sys.tables WHERE name like '%表名的模式%' AND type='U' FOR XML PATH('')

 

Set @sql=stuff(@sql,1,7,' ')

 

Select @sql

 

这样就可以把SQL语句显示出来了,需要执行的话只需要exec(@sql)就可以了。

 

这样语句不光可以用于查询数据,加入我要批量删除某一类的表 这样的操作也可以,但有个弊端,就是varchar(max)的容量有限,假如表或者语句太大,varchar(max)放不下的话,最终执行的SQL肯定达不到效果啦!

 

关联子查询

在上一家公司里面,彬哥教导我们,不要用子查询,会让查询速度变慢的,但是这位DBA教我用了联表子查询,原本的子查询放在FORM子句中;DBA教导的是把子查询放到JOIN子句中,当我提到说影响效率,DBA说不会,我也不明白了。这种语句说应用场景也比较多,我举个例子。

 

假如现在有一张成绩表,需要查询每个同学去除他整个学期所有测试中最高和最低分的结果,这种情况,关联的子查询适合了

 

SELECT a.* FROM Exam AS a LEFT JOIN

 

(SELECT [name],MAX(score) AS MaxScore,MIN(score) AS MinScore FROM Exam GROUP BY [name] HAVING MAX(score)MIN(score) ) AS b

 

ON a.name=b.name AND a.scoreb.MaxScore AND a.scoreb.MinScore

 

WHERE b.name IS NOT NULL

 

从下面开始则是个人积累阶段了

 

去除重复

去除重复会涉及到子查询,但子查询会分在FROM子句关联的子查询和直接在WHERE子句里面。共同点在于把视为重复的若干列先分组把他们的键查出来,然后在另一个查询中把最大或最小的保留,其余的DELETE,又拿Exam(id,name,score,subject)表为例,单科只需要一个成绩,其余的去掉。

 

DELETE FROM Exam WHERE id NOT IN ( SELECT MIN(id) FROM Exam GROUP BY name,subject )

 

另外一种在FROM子句的关联删除会在联表删除中列出来,假如没有主键,或组合主键不便于值用一个值去唯一标识这一行的,我想到的另一个办法是:建临时表#temptable,然后INSERT #temptable SELECT DESTINCT ,接着把原表删除,最后把临时表的数据INSERT去原表并把临时表删掉就得了,这个用在大数据量不知是否会合适。

 

联表更新

 

联表更新只是很基本的SQL语法而已,只是鄙人基本功不够扎实,就记录一下

 

UPDATE a SET a.value=b.monvalue WHERE table1 AS a INNER JOIN table2 AS B ON a.id=b.id WHERE …….

 

在这里顺便几下SQLite的

 

UPDATE table1 SET value=(SELECT monvalue FROM table2 where id=table1.id )

 

还有MySQL的

 

UPDATE table1 AS a,table2 AS b SET a.value=b.monvalue WHERE a.id=b.id

 

联表删除

 

与上面说的删除重复数据相照应,直接上SQL

 

DELETE a FROM Exam AS a LEFT JOIN ( SELECT MIN(id) FROM Exam GROUP BY name,subject ) AS b ON a.id=b.id WHERE b.id IS NULL

 

 

Case when

 

Case when 实际上有两种格式,简单一点的是case函数形式,如下面情况

 

Case sex

 

When '1' THEN '男'

 

WHEN '2' THEN '女'

 

ELSE '其他' END

 

另外一种形式叫case搜索函数,就像下面这样子

 

Case when sex='1' THEN ''

 

When sex='2' THEN '女'

 

ELSE '其他' END

 

个人认为case when 在查询中实现了分支判断的效果,单纯从外观语法上case函数形式会简介,但从效果来说case函数适合于分支判定是离散的值时适合;case搜索函数是适合于一定的范围,或者说自由度更广的一些判定条件,当然这个也包含了离散的值这个状况。但是case 搜索函数在判定好一个条件符合之后则会屏蔽后面合适的条件。像下面这条语句是能分清各个成绩的等级的

 

SELECT *,CASE

 

WHEN score >90 THEN '优秀'

 

WHEN score>80 THEN '良好'

 

WHEN score>60 THEN '合格'

 

ELSE '不合格' END FROM Exam

 

但是下面就只有合格与不合格两种等级了

 

SELECT *,CASE

 

WHEN score>60 THEN '合格'

 

WHEN score>80 THEN '良好'

 

WHEN score >90 THEN '优秀'

 

ELSE '不合格' END FROM Exam

 

之前鄙人一直在写case when … is null 这样的语句,老是不断尝试看语法又没出错,区分好case函数和case 搜索函数之后就明白,该用case when … is null 而不是case … when is null这样了。

 

行转列

现在数据库里面的表老是说横向表,纵向表,横向表就例如下面的表结构SubjectTest(id,name,subject,score)。假如要展示的结果是(学生,语文,数学,英语)这样的结果时则需要用到行转列

 

行转列有用到上面case when语句,大概是先把记录按姓名去分组,然后从分组中把各个分数用case分离出来,再用聚集函数求最值或者是求和,语句就这样子

 

select name, MAX( CASE [subject] WHEN '语文' THEN [score] ELSE 0 END ) AS '语文',

 

MAX( CASE [subject] WHEN '数学' THEN [score] ELSE 0 END ) AS '数学',

 

MAX( CASE [subject] WHEN '英语' THEN [score] ELSE 0 END ) AS '英语',

 

SUM([score]) AS '总分',

 

AVG([score]) AS '平均分'

 

FROM SubjectTest

 

GROUP BY [name]

 

原来也就这么一回事,当科目多了,MAX除了要多写几次外,还可以用用DBA妹子教的SQL拼凑生成把语句生成出来在执行,可惜视图View不支持这样子,唉!

 

在SQL Server 2005以上有另外一种方式pivot,直接上语句

 

SELECT * FROM subjecttest PIVOT( SUM(score) FOR [subject] IN( 语文,数学,英语 ) ) a

 

我很奇怪网上说的结果都是合并好的,而我的结果却是这个样子

积累一下SQL_MySQL

有行转列,也会有列转行,不过这个更没意思,但顺带也说说UNPIOVT

 

select name,'语文',语文 as score FROM SubjectTest

 

UNION ALL

 

select name,'数学',数学 as score FROM SubjectTest

 

UNION ALL

 

select name,'英语',英语 as score FROM SubjectTest

 

SELECT * FROM subjecttest UNPIVOT ( score for [subject] IN (语文,数学,英语) ) a

 

Month year day 函数

 

这几个函数用于求日期的相应部分,顾名思义是月份,年份,天数

 

DECLARE @testTimePoint DateTime

 

SET @testTimePoint='2015-10-23'

 

SELECT YEAR(@testTimePoint) AS 年,MONTH(@testTimePoint) AS 月,DAY(@testTimePoint) AS 日 

积累一下SQL_MySQL

Cast函数

 

Cast函数用于作为数据类型转换,使用它有三点要注意

 

(1)两个表达式的数据类型完全相同。;

 

(2)两个表达式可隐性转换。

 

(3)必须显式转换数据类型。

 

像下面这样子是会报错的

 

SELECT CAST('12.3' AS int)

 

因为'12.3'只能转到浮点数,不能转成整形,但是浮点数能转成整形,要让它能成功转,就得这样子

 

SELECT CAST( CAST('12.3' AS Float) AS Int)

积累一下SQL_MySQL

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

91

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

27

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

11

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

5

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

5

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

55

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号