热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

积累一下SQL_MySQL

动态SQL她当时教我最厉害的一招利用SQL生成SQL最终执行查询,大致就是通过sys.table查出表名,生成SQL并合并,最后exec执行。感觉还是比较有用。假设数据库中有一堆命名规范且结构相似的表,要查出这批表
动态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.score<>b.MaxScore AND a.score<>b.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 &#39;1&#39; THEN &#39;男&#39;

WHEN &#39;2&#39; THEN &#39;女&#39;

ELSE &#39;其他&#39; END

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

Case when sex=&#39;1&#39; THEN &#39;&#39;

When sex=&#39;2&#39; THEN &#39;女&#39;

ELSE &#39;其他&#39; END

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

SELECT *,CASE

WHEN score >90 THEN &#39;优秀&#39;

WHEN score>80 THEN &#39;良好&#39;

WHEN score>60 THEN &#39;合格&#39;

ELSE &#39;不合格&#39; END FROM Exam

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

SELECT *,CASE

WHEN score>60 THEN &#39;合格&#39;

WHEN score>80 THEN &#39;良好&#39;

WHEN score >90 THEN &#39;优秀&#39;

ELSE &#39;不合格&#39; 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 &#39;语文&#39; THEN [score] ELSE 0 END ) AS &#39;语文&#39;,

MAX( CASE [subject] WHEN &#39;数学&#39; THEN [score] ELSE 0 END ) AS &#39;数学&#39;,

MAX( CASE [subject] WHEN &#39;英语&#39; THEN [score] ELSE 0 END ) AS &#39;英语&#39;,

SUM([score]) AS &#39;总分&#39;,

AVG([score]) AS &#39;平均分&#39;

FROM SubjectTest

GROUP BY [name]

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

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

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

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

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

select name,&#39;语文&#39;,语文 as score FROM SubjectTest

UNION ALL

select name,&#39;数学&#39;,数学 as score FROM SubjectTest

UNION ALL

select name,&#39;英语&#39;,英语 as score FROM SubjectTest

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

Month year day 函数

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

DECLARE @testTimePoint DateTime

SET @testTimePoint=&#39;2015-10-23&#39;

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

Cast函数

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

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

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

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

像下面这样子是会报错的

SELECT CAST(&#39;12.3&#39; AS int)

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

SELECT CAST( CAST(&#39;12.3&#39; AS Float) AS Int)


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了通过mysql命令查看mysql的安装路径的方法,提供了相应的sql语句,并希望对读者有参考价值。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • 数据库(外键及其约束理解)(https:www.cnblogs.comchenxiaoheip6909318.html)My ... [详细]
  • 众筹商城与传统商城的区别及php众筹网站的程序源码
    本文介绍了众筹商城与传统商城的区别,包括所售产品和玩法不同以及运营方式不同。同时还提到了php众筹网站的程序源码和方维众筹的安装和环境问题。 ... [详细]
author-avatar
草千里2502902931
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有