首頁 資料庫 mysql教程 积累一下SQL_MySQL

积累一下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 Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

與MySQL中使用索引相比,全表掃描何時可以更快? 與MySQL中使用索引相比,全表掃描何時可以更快? Apr 09, 2025 am 12:05 AM

全表掃描在MySQL中可能比使用索引更快,具體情況包括:1)數據量較小時;2)查詢返回大量數據時;3)索引列不具備高選擇性時;4)複雜查詢時。通過分析查詢計劃、優化索引、避免過度索引和定期維護表,可以在實際應用中做出最優選擇。

可以在 Windows 7 上安裝 mysql 嗎 可以在 Windows 7 上安裝 mysql 嗎 Apr 08, 2025 pm 03:21 PM

是的,可以在 Windows 7 上安裝 MySQL,雖然微軟已停止支持 Windows 7,但 MySQL 仍兼容它。不過,安裝過程中需要注意以下幾點:下載適用於 Windows 的 MySQL 安裝程序。選擇合適的 MySQL 版本(社區版或企業版)。安裝過程中選擇適當的安裝目錄和字符集。設置 root 用戶密碼,並妥善保管。連接數據庫進行測試。注意 Windows 7 上的兼容性問題和安全性問題,建議升級到受支持的操作系統。

說明InnoDB全文搜索功能。 說明InnoDB全文搜索功能。 Apr 02, 2025 pm 06:09 PM

InnoDB的全文搜索功能非常强大,能够显著提高数据库查询效率和处理大量文本数据的能力。1)InnoDB通过倒排索引实现全文搜索,支持基本和高级搜索查询。2)使用MATCH和AGAINST关键字进行搜索,支持布尔模式和短语搜索。3)优化方法包括使用分词技术、定期重建索引和调整缓存大小,以提升性能和准确性。

InnoDB中的聚類索引和非簇索引(次級索引)之間的差異。 InnoDB中的聚類索引和非簇索引(次級索引)之間的差異。 Apr 02, 2025 pm 06:25 PM

聚集索引和非聚集索引的區別在於:1.聚集索引將數據行存儲在索引結構中,適合按主鍵查詢和範圍查詢。 2.非聚集索引存儲索引鍵值和數據行的指針,適用於非主鍵列查詢。

mysql:簡單的概念,用於輕鬆學習 mysql:簡單的概念,用於輕鬆學習 Apr 10, 2025 am 09:29 AM

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

mysql用戶和數據庫的關係 mysql用戶和數據庫的關係 Apr 08, 2025 pm 07:15 PM

MySQL 數據庫中,用戶和數據庫的關係通過權限和表定義。用戶擁有用戶名和密碼,用於訪問數據庫。權限通過 GRANT 命令授予,而表由 CREATE TABLE 命令創建。要建立用戶和數據庫之間的關係,需創建數據庫、創建用戶,然後授予權限。

說明不同類型的MySQL索引(B樹,哈希,全文,空間)。 說明不同類型的MySQL索引(B樹,哈希,全文,空間)。 Apr 02, 2025 pm 07:05 PM

MySQL支持四種索引類型:B-Tree、Hash、Full-text和Spatial。 1.B-Tree索引適用於等值查找、範圍查詢和排序。 2.Hash索引適用於等值查找,但不支持範圍查詢和排序。 3.Full-text索引用於全文搜索,適合處理大量文本數據。 4.Spatial索引用於地理空間數據查詢,適用於GIS應用。

mysql 和 mariadb 可以共存嗎 mysql 和 mariadb 可以共存嗎 Apr 08, 2025 pm 02:27 PM

MySQL 和 MariaDB 可以共存,但需要謹慎配置。關鍵在於為每個數據庫分配不同的端口號和數據目錄,並調整內存分配和緩存大小等參數。連接池、應用程序配置和版本差異也需要考慮,需要仔細測試和規劃以避免陷阱。在資源有限的情況下,同時運行兩個數據庫可能會導致性能問題。

See all articles