积累一下SQL_MySQL

May 30, 2016 pm 05:09 PM

动态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

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

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

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

Alter Table 문을 사용하여 MySQL에서 테이블을 어떻게 변경합니까? Alter Table 문을 사용하여 MySQL에서 테이블을 어떻게 변경합니까? Mar 19, 2025 pm 03:51 PM

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

MySQL 연결에 대한 SSL/TLS 암호화를 어떻게 구성합니까? MySQL 연결에 대한 SSL/TLS 암호화를 어떻게 구성합니까? Mar 18, 2025 pm 12:01 PM

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

MySQL에서 큰 데이터 세트를 어떻게 처리합니까? MySQL에서 큰 데이터 세트를 어떻게 처리합니까? Mar 21, 2025 pm 12:15 PM

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

인기있는 MySQL GUI 도구는 무엇입니까 (예 : MySQL Workbench, Phpmyadmin)? 인기있는 MySQL GUI 도구는 무엇입니까 (예 : MySQL Workbench, Phpmyadmin)? Mar 21, 2025 pm 06:28 PM

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

드롭 테이블 문을 사용하여 MySQL에서 테이블을 어떻게 드롭합니까? 드롭 테이블 문을 사용하여 MySQL에서 테이블을 어떻게 드롭합니까? Mar 19, 2025 pm 03:52 PM

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

JSON 열에서 인덱스를 어떻게 생성합니까? JSON 열에서 인덱스를 어떻게 생성합니까? Mar 21, 2025 pm 12:13 PM

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

외국 키를 사용하여 관계를 어떻게 표현합니까? 외국 키를 사용하여 관계를 어떻게 표현합니까? Mar 19, 2025 pm 03:48 PM

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

InnoDB 전체 텍스트 검색 기능을 설명하십시오. InnoDB 전체 텍스트 검색 기능을 설명하십시오. Apr 02, 2025 pm 06:09 PM

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

See all articles