「SQL」修訂間的差異
跳至導覽
跳至搜尋
小 (→MsSQL) |
(→SQL的版本) |
||
(未顯示同一使用者於中間所作的 41 次修訂) | |||
行 1: | 行 1: | ||
− | == | + | '''SQL'''(Structured Query Language) |
− | * [ | + | *{{wikipedia|SQL|lang=en}} |
+ | *{{wikipedia|SQL_syntax|lang=en}} | ||
+ | *{{wikibooks|Structured_Query_Language|lang=en}} | ||
+ | *{{wikiversity|SQL|lang=en}} | ||
+ | |||
+ | ==技術文件== | ||
+ | *ISO/IEC 9075 - ''Information technology — Database languages — SQL'' | ||
+ | *[https://www.w3schools.com/sql/ SQL Tutorial - W3Schools] | ||
+ | *[https://troels.arvin.dk/db/rdbms/ Comparison of different SQL implementations] | ||
+ | |||
+ | ==SQL的版本== | ||
+ | ;標準 | ||
+ | *SQL-86 | ||
+ | *SQL-89 | ||
+ | *{{wikipedia|SQL-92|lang=en}} | ||
+ | *{{wikipedia|SQL:1999|lang=en}} | ||
+ | *{{wikipedia|SQL:2003|lang=en}} | ||
+ | *{{wikipedia|SQL:2008|lang=en}} | ||
+ | *{{wikipedia|SQL:2011|lang=en}} | ||
+ | *{{wikipedia|SQL:2016|lang=en}} | ||
+ | *SQL:2019 | ||
+ | |||
+ | ;主要分支版本 | ||
+ | *[[T-SQL]],{{wikipedia|Transact-SQL|lang=en}} | ||
+ | *:用於:[[MS-SQL|Microsoft SQL Server]] | ||
+ | *[[PL/SQL]],{{wikipedia|PL/SQL|lang=en}} | ||
+ | *:用於:[[Oracle]] | ||
+ | *[[SQL/PSM]],{{wikipedia|SQL/PSM|lang=en}} | ||
+ | *:用於:[[MySQL]],[[MariaDB]] | ||
+ | *[[PL/pgSQL]],{{wikipedia|PL/pgSQL|lang=en}} | ||
+ | *:用於:[[PostgreSQL]] | ||
+ | *[[SQL PL]],{{wikipedia|SQL_PL|lang=en}} | ||
+ | *:用於:[[IBM DB2]] | ||
+ | |||
+ | ==SQL基本語法== | ||
+ | ===查詢(Select)=== | ||
+ | *{{wikipedia|Select_(SQL)|lang=en}} | ||
+ | ;基本模式 | ||
+ | <source lang="tsql"> | ||
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表] | ||
+ | WHERE [篩選條件] | ||
+ | ORDER BY [排序欄位] [ASC/DESC] | ||
+ | </source> | ||
+ | ;相同欄位的多個查詢結果串接(也可使用不同來源的資料表) | ||
+ | <source lang="tsql"> | ||
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表1] | ||
+ | WHERE [篩選條件1] | ||
+ | UNION | ||
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表2] | ||
+ | WHERE [篩選條件2] | ||
+ | </source> | ||
+ | |||
+ | ===插入(Insert)=== | ||
+ | *{{wikipedia|Insert_(SQL)|lang=en}} | ||
+ | ;基本模式 | ||
+ | <source lang="tsql"> | ||
+ | INSERT INTO [資料表] ([欄位1, 欄位2, ...]) | ||
+ | VALUES ([欄位值1, 欄位值2, ...]) | ||
+ | </source> | ||
+ | ;插入多筆資料(SQL Server 2008以上, 或是MySQL等才支援) | ||
+ | <source lang="tsql"> | ||
+ | INSERT INTO [資料表] VALUES | ||
+ | ([欄位值1, 欄位值2, ...]) | ||
+ | ,([欄位值1, 欄位值2, ...]) | ||
+ | ,([欄位值1, 欄位值2, ...]) | ||
+ | </source> | ||
+ | ;從另一個資料表取資料,插入到另一個資料表之中 | ||
+ | <source lang="tsql"> | ||
+ | INSERT INTO [資料表] ([欄位1, 欄位2, ...]) | ||
+ | SELECT ([欄位1, 欄位2, ...]) FROM [來源資料表] WHERE [篩選條件] | ||
+ | </source> | ||
+ | |||
+ | ===更新(Update)=== | ||
+ | *{{wikipedia|Update_(SQL)|lang=en}} | ||
+ | ;基本模式 | ||
+ | <source lang="tsql"> | ||
+ | UPDATE [資料表] SET [欄位1 = 欄位值1, 欄位2 = 欄位值2 ...] | ||
+ | WHERE [篩選條件] | ||
+ | </source> | ||
+ | ;從別的資料表中取出資料,更新到資料表 | ||
+ | <source lang="tsql"> | ||
+ | UPDATE [資料表] | ||
+ | SET [欄位1=a.欄位1, 欄位2=a.欄位2 ....] | ||
+ | FROM [來源資料表] AS a | ||
+ | WHERE [篩選條件] | ||
+ | </source> | ||
+ | |||
+ | ===刪除(Delete)=== | ||
+ | *{{wikipedia|Delete_(SQL)|lang=en}} | ||
+ | ;基本模式 | ||
+ | <source lang="tsql"> | ||
+ | DELETE FROM [資料表] WHERE [篩選條件] | ||
+ | </source> | ||
==SQL分頁select== | ==SQL分頁select== | ||
行 10: | 行 105: | ||
ORDER BY [排序欄位] [ASC/DESC] | ORDER BY [排序欄位] [ASC/DESC] | ||
</source> | </source> | ||
− | === | + | ===MS-SQL=== |
− | ====Type A==== | + | ====MS-SQL Type A==== |
* 無排序,在關聯式查詢時,可能導致每次查詢同一分頁的資料時,出來的資料都不一樣。 | * 無排序,在關聯式查詢時,可能導致每次查詢同一分頁的資料時,出來的資料都不一樣。 | ||
<source lang="tsql"> | <source lang="tsql"> | ||
行 33: | 行 128: | ||
</source> | </source> | ||
− | ====Type B==== | + | ====MS-SQL Type B==== |
− | * | + | * 有排序,又稱【夾擠式分頁查詢】。MS-SQL 2000以前,常見的分頁用語法。 |
<source lang="tsql"> | <source lang="tsql"> | ||
SELECT * FROM | SELECT * FROM | ||
行 51: | 行 146: | ||
ORDER BY [排序欄位] [DESC/ASC] | ORDER BY [排序欄位] [DESC/ASC] | ||
</source> | </source> | ||
+ | |||
+ | ====MS-SQL Type C==== | ||
+ | * MS-SQL 2005以後才有RANK()語法。需特別注意,當RANK()裡的排序條件只有1個欄位,且此欄位的值都一樣時,會導致RankNumber都會變成1,導致分頁失效,需在排序條件中加上一個有唯一值的欄位。 | ||
+ | <source lang="tsql"> | ||
+ | SELECT * FROM | ||
+ | ( | ||
+ | SELECT rank() over ( ORDER BY [排序欄位] [ASC/DESC] ) as RankNumber, * FROM | ||
+ | ( | ||
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表] | ||
+ | WHERE [篩選條件] | ||
+ | ) | ||
+ | as [資料表别名1] | ||
+ | ) as [資料表别名2] | ||
+ | WHERE RankNumber between [每頁長度*(第幾頁-1)] and [每頁長度*第幾頁] | ||
+ | </source> | ||
+ | |||
+ | ====MS-SQL Type D==== | ||
+ | * MS-SQL 2000可用,但Select時,不可包含PK用的欄位。(需透過暫存資料表操作) | ||
+ | * 參考資料:[http://blog.blueshop.com.tw/topcat/archive/2008/03/28/54623.aspx (SQL)抽獎,亂數抽出10筆中獎資料並排名] | ||
+ | <source lang="tsql"> | ||
+ | SELECT IDENTITY(int,1,1) as RankNumber, [欄位1, 欄位2, ...] | ||
+ | INTO [#暫存資料表名稱] | ||
+ | FROM [資料表] | ||
+ | ORDER BY [排序欄位] [ASC/DESC]; | ||
+ | |||
+ | SELECT * FROM [#暫存資料表名稱] | ||
+ | WHERE RankNumber between [每頁長度*(第幾頁-1)] and [每頁長度*第幾頁]; | ||
+ | |||
+ | drop table [#暫存資料表名稱]; | ||
+ | </source> | ||
+ | |||
+ | ====其他相關==== | ||
+ | * [http://blog.sina.com.tw/4907/article.php?pbgid=4907&entryid=3921 當DataGrid遇見100萬筆資料] | ||
+ | :(以SQL預存程序實作SQL-Sever的北風資料庫的分頁範例) | ||
+ | * [http://www.codeproject.com/KB/database/SQLServer2KPagingSorting.aspx SQL Server 2000 Paging and Sorting Using ROWCOUNT and SQL_VARIANT] | ||
===MySQL=== | ===MySQL=== | ||
行 61: | 行 192: | ||
</source> | </source> | ||
− | |||
− | |||
− | == | + | ===Oracle=== |
− | * [ | + | ====Oracle Type A==== |
− | * [ | + | *使用ROWNUM做分頁 |
− | * [ | + | *參照:[https://blogs.oracle.com/oraclemagazine/post/on-top-n-and-pagination-queries On Top-n and Pagination Queries] |
− | *[ | + | <source lang="oracle8"> |
− | * [ | + | SELECT * FROM ( |
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表] | ||
+ | WHERE [篩選條件] | ||
+ | ORDER BY [排序欄位] [ASC/DESC] | ||
+ | ) | ||
+ | WHERE ROWNUM >= [每頁長度*(第幾頁-1)+1] | ||
+ | AND ROWNUM <= [每頁長度*第幾頁] | ||
+ | </source> | ||
+ | ====Oracle Type B==== | ||
+ | *使用OFFSET與FETCH NEXT做分頁,據說是Oracle 12c開始可以用的寫法? | ||
+ | *參照:[https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html The result offset and fetch first clauses] | ||
+ | <source lang="oracle8"> | ||
+ | SELECT [欄位1, 欄位2, ...] | ||
+ | FROM [資料表] | ||
+ | WHERE [篩選條件] | ||
+ | ORDER BY [排序欄位] [ASC/DESC] | ||
+ | OFFSET [每頁長度*(第幾頁-1)] ROWS FETCH NEXT [每頁長度] ROWS ONLY; | ||
+ | </source> | ||
+ | |||
+ | ==關聯式查詢== | ||
+ | *模式1.資料表名稱都寫在from,關聯條件都寫在where | ||
+ | *模式2.join,關聯條件寫在各自的on (join關係見下圖) | ||
+ | *:圖檔出處:[https://www.facebook.com/photo.php?fbid=645876362117204&set=a.199337396771105.43932.199182533453258&type=1&theater Facebook(MSDN 台灣)] | ||
+ | [[File:SQL-Joins.png|600px]] | ||
+ | *模式3.子查詢 (可用於查詢的欄位或傳給篩選條件) | ||
+ | *:[https://docs.microsoft.com/zh-tw/sql/relational-databases/performance/subqueries?view=sql-server-ver15 子查詢 (SQL Server) - SQL Server | Microsoft Docs ] | ||
+ | |||
+ | ==相關== | ||
+ | *[[SQL語法比較]] | ||
+ | *[[資料清理]] | ||
+ | *[[CTE]] | ||
+ | |||
+ | ===Connection Strings=== | ||
+ | {{main|ConnectionString}} | ||
+ | |||
+ | ===SQL資料隱碼=== | ||
+ | {{main|SQL資料隱碼}} | ||
==FAQ== | ==FAQ== | ||
行 77: | 行 243: | ||
* MySQL 使用反單引號字元 '''`''' 來將衝突的Table或欄位的名稱包起來。 | * MySQL 使用反單引號字元 '''`''' 來將衝突的Table或欄位的名稱包起來。 | ||
− | === | + | ===跨資料庫轉換=== |
− | * | + | ;相關軟體 |
+ | * [http://www.ispirer.com/products SQLWays] | ||
+ | |||
+ | ===在實際運用上,到底該直接用SQL?還是用EF(LINQ)?或是用SQL預存程序?=== | ||
+ | *[https://blog.darkthread.net/blog/linq-or-direct-sql/ 閒聊:用 LINQ 還是自己寫 SQL?-黑暗執行緒] | ||
[[Category:SQL]] | [[Category:SQL]] | ||
+ | [[Category:資料分頁]] |
於 2022年11月14日 (一) 13:29 的最新修訂
SQL(Structured Query Language)
- 參照:『維基百科~SQL』
- 參照:『維基百科~SQL_syntax』
- 參照:『維基教科書~Structured_Query_Language』
- 參照:『維基學院~SQL』
技術文件
- ISO/IEC 9075 - Information technology — Database languages — SQL
- SQL Tutorial - W3Schools
- Comparison of different SQL implementations
SQL的版本
- 標準
- SQL-86
- SQL-89
- 參照:『維基百科~SQL-92』
- 參照:『維基百科~SQL:1999』
- 參照:『維基百科~SQL:2003』
- 參照:『維基百科~SQL:2008』
- 參照:『維基百科~SQL:2011』
- 參照:『維基百科~SQL:2016』
- SQL:2019
- 主要分支版本
- T-SQL,參照:『維基百科~Transact-SQL』
- PL/SQL,參照:『維基百科~PL/SQL』
- 用於:Oracle
- SQL/PSM,參照:『維基百科~SQL/PSM』
- PL/pgSQL,參照:『維基百科~PL/pgSQL』
- 用於:PostgreSQL
- SQL PL,參照:『維基百科~SQL_PL』
- 用於:IBM DB2
SQL基本語法
查詢(Select)
- 參照:『維基百科~Select_(SQL)』
- 基本模式
SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [ASC/DESC]
- 相同欄位的多個查詢結果串接(也可使用不同來源的資料表)
SELECT [欄位1, 欄位2, ...] FROM [資料表1] WHERE [篩選條件1] UNION SELECT [欄位1, 欄位2, ...] FROM [資料表2] WHERE [篩選條件2]
插入(Insert)
- 參照:『維基百科~Insert_(SQL)』
- 基本模式
INSERT INTO [資料表] ([欄位1, 欄位2, ...]) VALUES ([欄位值1, 欄位值2, ...])
- 插入多筆資料(SQL Server 2008以上, 或是MySQL等才支援)
INSERT INTO [資料表] VALUES ([欄位值1, 欄位值2, ...]) ,([欄位值1, 欄位值2, ...]) ,([欄位值1, 欄位值2, ...])
- 從另一個資料表取資料,插入到另一個資料表之中
INSERT INTO [資料表] ([欄位1, 欄位2, ...]) SELECT ([欄位1, 欄位2, ...]) FROM [來源資料表] WHERE [篩選條件]
更新(Update)
- 參照:『維基百科~Update_(SQL)』
- 基本模式
UPDATE [資料表] SET [欄位1 = 欄位值1, 欄位2 = 欄位值2 ...] WHERE [篩選條件]
- 從別的資料表中取出資料,更新到資料表
UPDATE [資料表] SET [欄位1=a.欄位1, 欄位2=a.欄位2 ....] FROM [來源資料表] AS a WHERE [篩選條件]
刪除(Delete)
- 參照:『維基百科~Delete_(SQL)』
- 基本模式
DELETE FROM [資料表] WHERE [篩選條件]
SQL分頁select
分頁前SQL
SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [ASC/DESC]
MS-SQL
MS-SQL Type A
- 無排序,在關聯式查詢時,可能導致每次查詢同一分頁的資料時,出來的資料都不一樣。
SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [主要索引欄位] IN ( SELECT * FROM ( SELECT TOP [每頁長度*第幾頁] [主要索引欄位] FROM [資料表] WHERE [篩選條件] ) as [資料表别名1] WHERE [主要索引欄位] NOT IN ( SELECT TOP [每頁長度] [主要索引欄位] FROM [資料表] WHERE [篩選條件] ) )
MS-SQL Type B
- 有排序,又稱【夾擠式分頁查詢】。MS-SQL 2000以前,常見的分頁用語法。
SELECT * FROM ( SELECT TOP [每頁長度] * FROM ( SELECT TOP [每頁長度*第幾頁] [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [DESC/ASC] ) as [資料表别名1] ORDER BY [排序欄位] [ASC/DESC] ) as [資料表别名2] ORDER BY [排序欄位] [DESC/ASC]
MS-SQL Type C
- MS-SQL 2005以後才有RANK()語法。需特別注意,當RANK()裡的排序條件只有1個欄位,且此欄位的值都一樣時,會導致RankNumber都會變成1,導致分頁失效,需在排序條件中加上一個有唯一值的欄位。
SELECT * FROM ( SELECT rank() over ( ORDER BY [排序欄位] [ASC/DESC] ) as RankNumber, * FROM ( SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ) as [資料表别名1] ) as [資料表别名2] WHERE RankNumber between [每頁長度*(第幾頁-1)] and [每頁長度*第幾頁]
MS-SQL Type D
- MS-SQL 2000可用,但Select時,不可包含PK用的欄位。(需透過暫存資料表操作)
- 參考資料:(SQL)抽獎,亂數抽出10筆中獎資料並排名
SELECT IDENTITY(int,1,1) as RankNumber, [欄位1, 欄位2, ...] INTO [#暫存資料表名稱] FROM [資料表] ORDER BY [排序欄位] [ASC/DESC]; SELECT * FROM [#暫存資料表名稱] WHERE RankNumber between [每頁長度*(第幾頁-1)] and [每頁長度*第幾頁]; drop table [#暫存資料表名稱];
其他相關
- (以SQL預存程序實作SQL-Sever的北風資料庫的分頁範例)
MySQL
SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [ASC/DESC] LIMIT [每頁長度] OFFSET [每頁長度*第幾頁]
Oracle
Oracle Type A
- 使用ROWNUM做分頁
- 參照:On Top-n and Pagination Queries
SELECT * FROM ( SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [ASC/DESC] ) WHERE ROWNUM >= [每頁長度*(第幾頁-1)+1] AND ROWNUM <= [每頁長度*第幾頁]
Oracle Type B
- 使用OFFSET與FETCH NEXT做分頁,據說是Oracle 12c開始可以用的寫法?
- 參照:The result offset and fetch first clauses
SELECT [欄位1, 欄位2, ...] FROM [資料表] WHERE [篩選條件] ORDER BY [排序欄位] [ASC/DESC] OFFSET [每頁長度*(第幾頁-1)] ROWS FETCH NEXT [每頁長度] ROWS ONLY;
關聯式查詢
- 模式1.資料表名稱都寫在from,關聯條件都寫在where
- 模式2.join,關聯條件寫在各自的on (join關係見下圖)
- 圖檔出處:Facebook(MSDN 台灣)
- 模式3.子查詢 (可用於查詢的欄位或傳給篩選條件)
相關
Connection Strings
SQL資料隱碼
FAQ
當Table或欄位的名稱衝到SQL預設的保留字時
- MS-SQL 或 MS-Access 使用 [與] 來將衝突的Table或欄位的名稱包起來。
- Oracle 或 IBM-DB2 或 PostgreSQL 使用雙引號字元 " 來將衝突的Table或欄位的名稱包起來。
- MySQL 使用反單引號字元 ` 來將衝突的Table或欄位的名稱包起來。
跨資料庫轉換
- 相關軟體