积累一下SQL_MySQL
动态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
我很奇怪网上说的结果都是合并好的,而我的结果却是这个样子
有行转列,也会有列转行,不过这个更没意思,但顺带也说说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 日
Cast函数
Cast函数用于作为数据类型转换,使用它有三点要注意
(1)两个表达式的数据类型完全相同。;
(2)两个表达式可隐性转换。
(3)必须显式转换数据类型。
像下面这样子是会报错的
SELECT CAST('12.3' AS int)
因为'12.3'只能转到浮点数,不能转成整形,但是浮点数能转成整形,要让它能成功转,就得这样子
SELECT CAST( CAST('12.3' AS Float) AS Int)

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사는 MySQL의 Alter Table 문을 사용하여 열 추가/드롭 테이블/열 변경 및 열 데이터 유형 변경을 포함하여 테이블을 수정하는 것에 대해 설명합니다.

기사는 인증서 생성 및 확인을 포함하여 MySQL에 대한 SSL/TLS 암호화 구성에 대해 설명합니다. 주요 문제는 자체 서명 인증서의 보안 영향을 사용하는 것입니다. [문자 수 : 159]

기사는 MySQL에서 파티셔닝, 샤딩, 인덱싱 및 쿼리 최적화를 포함하여 대규모 데이터 세트를 처리하기위한 전략에 대해 설명합니다.

기사는 MySQL Workbench 및 Phpmyadmin과 같은 인기있는 MySQL GUI 도구에 대해 논의하여 초보자 및 고급 사용자를위한 기능과 적합성을 비교합니다. [159 자].

이 기사에서는 Drop Table 문을 사용하여 MySQL에서 테이블을 떨어 뜨리는 것에 대해 설명하여 예방 조치와 위험을 강조합니다. 백업 없이는 행동이 돌이킬 수 없으며 복구 방법 및 잠재적 생산 환경 위험을 상세하게합니다.

이 기사에서는 PostgreSQL, MySQL 및 MongoDB와 같은 다양한 데이터베이스에서 JSON 열에서 인덱스를 작성하여 쿼리 성능을 향상시킵니다. 특정 JSON 경로를 인덱싱하는 구문 및 이점을 설명하고 지원되는 데이터베이스 시스템을 나열합니다.

기사는 외국 열쇠를 사용하여 데이터베이스의 관계를 나타내고 모범 사례, 데이터 무결성 및 피할 수있는 일반적인 함정에 중점을 둡니다.

InnoDB의 전체 텍스트 검색 기능은 매우 강력하여 데이터베이스 쿼리 효율성과 대량의 텍스트 데이터를 처리 할 수있는 능력을 크게 향상시킬 수 있습니다. 1) InnoDB는 기본 및 고급 검색 쿼리를 지원하는 역 색인화를 통해 전체 텍스트 검색을 구현합니다. 2) 매치 및 키워드를 사용하여 검색, 부울 모드 및 문구 검색을 지원합니다. 3) 최적화 방법에는 워드 세분화 기술 사용, 인덱스의 주기적 재건 및 캐시 크기 조정, 성능과 정확도를 향상시키는 것이 포함됩니다.
