SQL基本操作

SQL 操作

檢索數據 SELECT

檢索數據

-- 檢索單個列
SELECT 列名 FROM table_name;-- 檢索多個列
SELECT1,2 FROM table_name;-- 檢索所有列
SELECT * FROM table_name;-- 檢索不同的值
SELECT DISTINCT 列名 FROM table_name;

限制檢索結果

-- SQL Server / Access
SELECT TOP 5 列名 FROM table_name;-- DB2
SELECT 列名 FROM table_name FETCH FIRST 5 ROWS ONLY;-- Oracle
SELECT prod_name FROM table_name WHERE ROWNUM <= 5;-- MySQL / MariaDB / PostgreSQL / SQLite
SELECT prod_name FROM table_name LIMIT 5;-- MySQL 從第六行開始,檢索五行
SELECT prod_name FROM table_name LIMIT 5 OFFSET 6;-- MySQL 與 MariaSQL 快捷鍵,上一條語句等價于:
SELECT prod_name FROM table_name LIMIT 5,6

排序檢索數據 ORDER BY

-- 按單個列排序,默認從小到大
SELECT field1, field2 from table_name ORDER BY field1;-- 按多個列排序,先按第一個排,第一個相同再按第二個排
SELECT field1, field2 from table_name ORDER BY field1, field2;-- 按列位置排序
SELECT field1, field2 from table_name ORDER BY 4,5;-- 降序排序,與DESC相對的是ASC,但ASC是默認的,DESC只作用于他前面的那一列
SELECT field1, field2 from table_name ORDER BY field1 DESC,field2 DESC;

過濾數據 WHERE

-- ORDER BY 語句應該始終放在最后
SELECT field1, field2 FROM table_name WHERE field1 = 3;

WHERE操作符

操作符說明
=等于
!=或<>不等于
<(>)小于(大于)
<= (》=)小于等于(大于等于)
!<不小于
!>不大于
BETWEEN在指定兩個值之間
IS NULL為NULL值
-- 范圍檢查,范圍需要用AND連接,包括邊界
SELECT * FROM stu WHERE grade BETWEEN 70 AND 100;
+----+----------+-----+-------+---------------------+
| id | name     | sex | grade | birthday            |
+----+----------+-----+-------+---------------------+
|  1 | zhangsan | boy |    99 | 2019-09-12 19:21:31 |
|  3 | wangwu   | boy |    77 | 2019-09-03 19:22:52 |
|  4 | zhaoliu  | boy |    77 | 2019-09-10 19:28:22 |
+----+----------+-----+-------+---------------------+
3 rows in set (0.33 sec)

高級數據過濾

-- AND 操作
SELECT * FROM stu WHERE grade>90 AND sex = "boy";-- OR 操作
SELECT * FROM stu WHERE grade > 90 OR grade < 60;-- IN 操作
SELECT * FROM stu WHERE name IN ('zhangsan', "lisi");-- NOT操作
SELECT * FROM stu WHERE NOT name IN ('zhangsan', "lisi");
  • AND 操作符優先級高于OR,可以加括號改變優先級
  • IN比OR執行更快
  • IN可以包含其他SELECT語句
  • NOT否定跟在它后面的語句

使用通配符進行數據過濾 LIKE

通配符作用
%匹配任何字符出現任意次
_匹配單個字符
[]匹配指定位置的一個字符(只有SQL Server支持)
-- 匹配name中帶有n的字段
select * from stu where name like "%n%";-- 匹配name以z或w開頭的字段(SQL Server)
select * from stu where name like "[zw]%";
  • 通配符搜索耗時比其他搜索長,不要依賴于通配符搜索

創建計算字段

計算字段并不存在于數據庫,只是在執行SELECT語句時生成的

拼接字段

DBMS符號
Access, SQL Server+
DB2,Oracle,PostgreSQL,SQLite,Open Office Base||
Mysql,MariaDB使用Concat()函數
-- SQL Server
SELECT name + "(" + grade + ")" FROM stu ORDER BY grade;-- MySQL
SELECT CONCAT(name,"(",grade,")") FROM stu ORDER BY grade;
+----------------------------+
| CONCAT(name,"(",grade,")") |
+----------------------------+
| lisi(66)                   |
| wangwu(77)                 |
| zhaoliu(77)                |
| zhangsan(99)               |
+----------------------------+

使用別名

-- SQL Server
SELECT
name + "(" + grade + ")" AS new_name
FROM stu ORDER BY grade;-- MySQL
SELECT CONCAT(name,"(",grade,")") AS new_name
FROM stu ORDER BY grade;
+--------------+
| new_name     |
+--------------+
| lisi(66)     |
| wangwu(77)   |
| zhaoliu(77)  |
| zhangsan(99) |
+--------------+

執行算數運算

支持 +,-,*,/

SELECT * ,
grade*0.1 AS new_grade
FROM stu ORDER BY grade;
+----+----------+-----+-------+---------------------+-----------+
| id | name     | sex | grade | birthday            | new_grade |
+----+----------+-----+-------+---------------------+-----------+
|  2 | lisi     | boy |    66 | 2019-09-04 19:22:05 |       6.6 |
|  3 | wangwu   | boy |    77 | 2019-09-03 19:22:52 |       7.7 |
|  4 | zhaoliu  | boy |    77 | 2019-09-10 19:28:22 |       7.7 |
|  1 | zhangsan | boy |    99 | 2019-09-12 19:21:31 |       9.9 |
+----+----------+-----+-------+---------------------+-----------+
4 rows in set (0.00 sec)

函數

每個DBMS都支持自己特定的函數,只有少數函數被大多DBMS支持

數據處理函數

文本處理函數

函數說明
LEFT()返回字符串左邊的字符
RIGHT()返回字符串右邊字符
LENGTH()或DATALENGTH()或LEN()返回字符串長度
LOWER() Access使用LCASE()將字符串轉換為小寫
UPPER() Access使用UCASE()將字符串轉換為大寫
LTRIM()去掉字符串左邊空格
RTRIM()去掉字符串右邊空格
SOUNDEX()返回字符串的SOUNDEX值
  • soundex是判斷讀音是不是相同,可惜中文不行,有趣的是這個算法發明的時間比計算機發明的時間還早,哈哈哈
mysql> SELECT * FROM stu WHERE SOUNDEX(name) = SOUNDEX("enn");
+----+------+-----+-------+---------------------+
| id | name | sex | grade | birthday            |
+----+------+-----+-------+---------------------+
|  5 | en   | boy |    33 | 2019-09-29 20:41:41 |
+----+------+-----+-------+---------------------+

時間日期處理函數

-- SQL Server
SELECT * FROM stu WHERE DATEPART(yy, birthday) = 2012;-- Access
SELECT * FROM stu WHERE DATEPART("yyyy", birthday) = 2012;-- PostgreSQL
SELECT * FROM stu WHERE DATE_PART('year', birthday) = 2012;-- Oracle
SELECT * FROM stu WHERE to_number(to_char(birthday,'yyyy')) = 2012;-- MySQL MairiaDB
SELECT * FROM stu WHERE YEAR(birthday) = 2012;-- SQLite
SELECT * FROM stu WHERE strftime('%Y', birthday) = 2102;

數值處理函數

函數說明
ABS()絕對值
COS(),SIN(),TAN()余弦,正弦,正切
PI()圓周率
EXP()指數
SQRT()平方根

聚集函數

SQL聚集函數

函數說明
AVG()返回某列平均值
COUNT()返回某列行數
MAX() MIN()返回某列最大最小值
SUM()返回某列之和
  • COUNT(*)對表中所有行計數,不管是否包含空值
  • COUNT(列)對特定列中具有特定值的行計數,忽略空值
  • 可以使用DISTINCT聚集不同的值(Access不支持)
SELECT
COUNT(*) AS count_num,
AVG(DISTINCT grade) AS avg_grade,
MAX(grade) AS max_grade,
MIN(grade) AS min_grade,
SUM(grade) AS sun_grade
FROM stu;
+-----------+-----------+-----------+-----------+-----------+
| count_num | avg_grade | max_grade | min_grade | sun_grade |
+-----------+-----------+-----------+-----------+-----------+
|         6 |   74.2000 |        99 |        33 |       448 |
+-----------+-----------+-----------+-----------+-----------+
1 row in set (0.00 sec)

分組數據 GROUP BY

select grade, count(*) AS nums from stu group by grade;
+-------+------+
| grade | nums |
+-------+------+
|    99 |    1 |
|    66 |    1 |
|    77 |    2 |
|    33 |    1 |
|    96 |    1 |
+-------+------+
5 rows in set (0.00 sec)
  • GROUP BY 子句可以包含任意數目的列,因此可以對分組進行嵌套,進行更細致的分組
  • 如果嵌套了分組,數據將在最后指定的分組上進行匯總。(所有列一起計算)
  • GROUP BY 子句中列出的每一列都必須是檢索列或有效的表達式(不能是聚集函數),如果在SELECT中使用表達式,則必須在GROUP子句中指定相同的表達式,不能使用別名.
  • 大多數DBMS不允許GROUP BY 帶有長度可變的數據類型
  • 除聚集計算語句外,SELECT語句中的每一列都必須在GROUP BY中給出
  • 如果分組列中包含一個NULL值,則NULL作為一個分組返回,多個NULL作為一個分組。
  • GROUP BY應該出現在WHERE之前,ORDER BY 之前。

過濾分組 HAVING

select grade, count(*) AS nums from stu group by grade having grade > 60;
+-------+------+
| grade | nums |
+-------+------+
|    99 |    1 |
|    66 |    1 |
|    77 |    2 |
|    96 |    1 |
+-------+------+
4 rows in set (0.10 sec)

HAVING 與 WHERE 的區別:
WHERE在數據分組前進行過濾,HAVING在數據分組后進行過濾,WHERE排除的行不包括在分組中,這可能會改變計算值,從而影響HAVING中基于這些值過濾掉的分組。
如果不指定GROUP BY 大多數DBMS會同等對待他們,不過,使用HAVING時應該結合GROUP BY 而WHERE應該用于標準的行級過濾。

分組和排序

GROUP BY 與 ORDER BY 經常完成相同的工作,但他們非常不同,ORDER BY 是對產生的輸出進行排序,而GROUP BY 是對行進行排序,但輸出的可能不是分組的順序,所以在使用GROUP BY時,也應該給出ORDER BY 子句。

--- 除ACCESS外,大部分DBMS支持用別名排序
select grade, count(*) AS nums from stugroup by grade having grade > 60order by count(*);
+-------+------+
| grade | nums |
+-------+------+
|    66 |    1 |
|    96 |    1 |
|    99 |    1 |
|    77 |    2 |
+-------+------+

子查詢

select * from songs where singer in  -> (select id from singer where name = "張靚穎");
+-----------+---------------------+--------------------------------------------------------+--------+
| id        | name                | link                                                   | singer |
+-----------+---------------------+--------------------------------------------------------+--------+
|    169794 | 天下無雙            | http://music.163.com/song/media/outer/url?id=169794    |  10561 |
|    327089 | 畫心                | http://music.163.com/song/media/outer/url?id=327089    |  10561 |
|    327163 | 我們說好的          | http://music.163.com/song/media/outer/url?id=327163    |  10561 |
|    327225 | 如果愛下去          | http://music.163.com/song/media/outer/url?id=327225    |  10561 |
|   5233037 | 另一個天堂          | http://music.163.com/song/media/outer/url?id=5233037   |  10561 |
|  31877130 | 餓狼傳說 (Live)     | http://music.163.com/song/media/outer/url?id=31877130  |  10561 |
| 431853688 | 我的夢 (Live)       | http://music.163.com/song/media/outer/url?id=431853688 |  10561 |
+-----------+---------------------+--------------------------------------------------------+--------+
7 rows in set (0.25 sec)
  • 子查詢可以嵌套,但出于效能考慮,不應該嵌套過多。

作為計算字段使用子查詢

mysql> SELECT name,-> (SELECT COUNT(*) FROM songs WHERE songs.singer = singer.id) AS nums-> FROM singer WHERE type IN-> (SELECT id FROM singer_type WHERE type = "華語男歌手")-> ORDER BY name-> LIMIT 5;
+-----------------+------+
| name            | nums |
+-----------------+------+
| “阿蘭姐”        |   50 |
| 023 GC          |    0 |
| A3              |   32 |
| abduwali tohti  |    8 |
| ABSDJHONG       |   22 |
+-----------------+------+
5 rows in set (0.69 sec)

聯結表

聯結是一種機制,用來在一條SELECT語句中關聯表,因此,稱為聯結

--- 等值聯結
mysql> SELECT songs.name,link,singer.name FROM songs,singer-> WHERE songs.singer = singer.id-> LIMIT 5;
+-----------------+----------------------------------------------------+--------+
| name            | link                                               | name   |
+-----------------+----------------------------------------------------+--------+
| Happy Birth Day | http://music.163.com/song/media/outer/url?id=59867 | 阿信   |
| 幾年了          | http://music.163.com/song/media/outer/url?id=59870 | 阿杜   |
| Valentines Day | http://music.163.com/song/media/outer/url?id=59875 | 阿杜   |
| 再唱一首        | http://music.163.com/song/media/outer/url?id=59877 | 阿杜   |
| 圣堂之門        | http://music.163.com/song/media/outer/url?id=59886 | 阿沁   |
+-----------------+----------------------------------------------------+--------+
5 rows in set (0.01 sec)
  • 創建表聯結時的WGERE語句非常重要,他作為過濾條件,只包含那些匹配給定條件的行,沒有聯結條件則會返回要聯結的表的笛卡爾積(叉聯結)
  • 完全限定名:引用列可能出現歧義,這種情況應該使用表名.列名的完全限定名

內連接(inner-join)

上面的等值連接也叫內連接,可以顯式聲明聯結類型

mysql> SELECT songs.name, link, singer.name AS singer-> FROM songs INNER JOIN singer ON-> songs.singer = singer.id-> LIMIT 5;
+-----------------+----------------------------------------------------+--------+
| name            | link                                               | singer |
+-----------------+----------------------------------------------------+--------+
| Happy Birth Day | http://music.163.com/song/media/outer/url?id=59867 | 阿信   |
| 幾年了          | http://music.163.com/song/media/outer/url?id=59870 | 阿杜   |
| Valentines Day | http://music.163.com/song/media/outer/url?id=59875 | 阿杜   |
| 再唱一首        | http://music.163.com/song/media/outer/url?id=59877 | 阿杜   |
| 圣堂之門        | http://music.163.com/song/media/outer/url?id=59886 | 阿沁   |
+-----------------+----------------------------------------------------+--------+
5 rows in set (0.00 sec)
  • SQL本身不限制聯結表的數量,但許多DBMS有限制
  • 聯結表越多,性能下降越厲害
  • 允許使用表別名(Oracle 不用 AS)

自聯結(self-join)

mysql> SELECT s1.name,s1.singer-> FROM songs AS s1,songs AS s2-> WHERE s1.singer = s2.singer AND s2.name="光年之外";
+-----------------------------+--------+
| name                        | singer |
+-----------------------------+--------+
| 來自天堂的魔鬼              |   7763 |
|(Live Piano Session II)  |   7763 |
| 光年之外                    |   7763 |
| 斷訊                        | 916042 |
| 光年之外                    | 916042 |
| 那個她                      | 916042 |
+-----------------------------+--------+
6 rows in set (4.53 sec)
  • 聯結中的兩張表是同一張表,必須使用別名區分。
  • 許多DBMS處理自聯結比處理子查詢快。

自然聯結

自然聯結是一種特殊的等值聯結(內聯結),他要求兩個關系中進行比較的分量必須是同名的屬性組,并且在結果中把重復的屬性列去掉,事實上,我們迄今為止建立的每個內聯結都是自然聯結,也很可能永遠都不會用到不是自然聯結的內聯結。通常對一個表使用通配符(SELECT *)其他表使用明確的子集來完成。

mysql> SELECT s.* ,e.name-> FROM songs AS s,singer AS e-> WHERE s.singer = e.id AND e.name = "袁婭維";

外聯結

兩個關系R和S在做自然連接時,他們在公共屬性上值相等的元組構成新的關系,但是關系R中某些元組可能在關系S中不存在公共屬性上值相等的元組,從而造成R中的這些元組被舍棄了,同樣的S中的元組也有可能被舍棄,這些被舍棄的元組被稱為 懸浮元組

如果把懸浮元組也保存到結果關系中,而在其他屬性上填空值,這種聯結叫做外聯結,如果只保留左邊關系R中的懸浮元組就叫做左外連接,如果只保留右邊關系S中的懸浮元組就叫做右外連接。

-- 原來表的數據
mysql> select * from r;
+----+----+----+
| A  | B  | C  |
+----+----+----+
| a1 | b1 | 5  |
| a1 | b2 | 6  |
| a2 | b3 | 8  |
| a2 | b4 | 12 |
+----+----+----+
4 rows in set (0.00 sec)mysql> select * from s;
+----+----+
| B  | E  |
+----+----+
| b1 | 3  |
| b2 | 7  |
| b3 | 10 |
| b3 | 2  |
| b5 | 2  |
+----+----+
5 rows in set (0.00 sec)-- 左外連接
mysql> SELECT r.*,s.*-> FROM r LEFT OUTER JOIN s-> ON r.b = s.b;
+----+----+----+------+------+
| A  | B  | C  | B    | E    |
+----+----+----+------+------+
| a1 | b1 | 5  | b1   | 3    |
| a1 | b2 | 6  | b2   | 7    |
| a2 | b3 | 8  | b3   | 10   |
| a2 | b3 | 8  | b3   | 2    |
| a2 | b4 | 12 | NULL | NULL |
+----+----+----+------+------+
5 rows in set (0.00 sec)-- 右外聯結
mysql> SELECT r.*,s.*-> FROM r RIGHT OUTER JOIN s-> ON r.b = s.b;
+------+------+------+----+----+
| A    | B    | C    | B  | E  |
+------+------+------+----+----+
| a1   | b1   | 5    | b1 | 3  |
| a1   | b2   | 6    | b2 | 7  |
| a2   | b3   | 8    | b3 | 10 |
| a2   | b3   | 8    | b3 | 2  |
| NULL | NULL | NULL | b5 | 2  |
+------+------+------+----+----+
5 rows in set (0.00 sec)

還有一種全外聯結(FULL OUTER JOIN)包含兩個表中不相關的行,Access,MariaDB,MySQL,Open Office Base,SQLite不支持。

使用帶聚集函數的聯結

組合查詢 UNION

mysql> SELECT id, name from singer where name="阿沁"-> UNION-> SELECT name, id FROM singer WHERE name="林俊呈";
+-----------+----------+
| id        | name     |
+-----------+----------+
| 1872      | 阿沁     |
| 林俊呈    | 30107224 |
+-----------+----------+
2 rows in set (0.07 sec)
  • UNION 語句中必須包含相同的列,表達式或聚集函數(次序可以不同)
  • 列數據類型必須兼容
  • 只能使用一條ORDER BY 語句,位于最后一個select之后
  • UNION會自動刪除相同的行,如果不希望這樣,可以使用 UNION ALL

插入數據 INSERT

-- 不安全
mysql> INSERT INTO stu-> VALUES(-> 7,-> "dapeng",-> "girl",-> 99,-> "2019-10-9 10:11:21");
Query OK, 1 row affected (0.09 sec)

應該給出列名(雖然更加麻煩),尤其是你只打算插入部分行時。

mysql> INSERT INTO stu(id,->                 name,->                 sex,->                 grade)-> VALUES(8,->        "xiaowei",->        "girl",->        99);
Query OK, 1 row affected (0.05 sec)

插入檢索出的數據

mysql> INSERT INTO stu(name,->                 sex,->                 grade,->                 birthday)-> SELECT name,->        sex,->        grade,->        birthday-> FROM stu WHERE id = 1;
Query OK, 1 row affected (1.67 sec)
Records: 1  Duplicates: 0  Warnings: 0
  • 可以從本表中檢索插入,也可以從其他表中檢索插入。

從一個表復制到另一個表 SELECT INTO

  • DB2 不支持
-- MariaDB,MySQL,Oracle,PostgreSQL,SQLite
mysql> CREATE TABLE s_copy AS SELECT * FROM s;
Query OK, 5 rows affected (0.11 sec)
Records: 5  Duplicates: 0  Warnings: 0mysql> show tables;
+----------------------+
| Tables_in_sqlstudent |
+----------------------+
| r                    |
| s                    |
| s_copy               |
| stu                  |
+----------------------+
4 rows in set (0.00 sec)-- 其他DBMS
SELECT * INTO s_copy FROM s;

更新和刪除數據

mysql> UPDATE stu-> SET sex="boy",->     birthday=Null-> WHERE name = "dapeng";
Query OK, 1 row affected (0.08 sec)
Rows matched: 1  Changed: 1  Warnings: 0
  • 可以只寫一條UPDATE語句更新多列數據
  • 部分DBMS支持FROM語法,把別的表中的數據更新到這張表里
  • 不寫WHERE語句會更新所有行
  • UPDATE允許使用子查詢
mysql> DELETE FROM stu WHERE id=2;
Query OK, 1 row affected (0.04 sec)
  • 不寫WHERE語句會刪除所有數據
  • DELETE不需要列名或通配符,應為它刪除的是整個行
  • 如果想刪除所有行,應該使用TRUNCATE TABLE,它更快,所以無論何時,使用DELETE時記得加WHERE

創建和操縱表

刪除表

mysql> DROP TABLE s_copy;
Query OK, 0 rows affected (0.07 sec)
  • 沒提示確認

創建表

mysql> CREATE TABLE Products(-> id int(255) NOT NULL,-> name VARCHAR(100) NULL-> );
Query OK, 0 rows affected (0.08 sec)
  • 不同DBMS的表創建語句有差異
  • 創建新表時,指定的表名必須不存在
  • 創建表時字段允許為空則指定NULL,否則,如果要求插入時必須給出值,則指定為NOT NULL
  • NULL不同于'',前者是沒有值,后者是空字符串
  • 不指定時大部分DBMS默認為NULL,但DB2不指定會報錯
  • 允許NULL值的列不允許作為主鍵
  • DEFAULT 用來指定默認值,常用于時間或時間戳列

獲取系統日期

DBMS函數
AccessNOW()
DB2CURRENT_DATE
MySQLCURRENT_TIMESTAMP
OracleSYSDATE
PostgreSQLCURRENT_DATE
SQL ServerGETDATE()
SQLitedate(‘now’)
CREATE TABLE User
(id      INT(255)        NOT NULL,name    VARCHAR(255)    NOT NULL,create_time timestamp   DEFAULT CURRENT_TIMESTAMP
);

更新表 ALTER TABLE

  • 一般不要在表中包含數據時更新表
  • 所有DBMS都允許怎加列,不過對所增加列的數據類型(NULL和DEFAULT的使用)有限制
  • 許多DBMS不允許刪除或更改列
  • 許多DBMS允許重命名列
-- 增加列
ALTER TABLE User ADD phone CHAR(20);mysql> DESCRIBE User;
+-------------+--------------+------+-----+-------------------+-------------------+
| Field       | Type         | Null | Key | Default           | Extra             |
+-------------+--------------+------+-----+-------------------+-------------------+
| id          | int(255)     | NO   |     | NULL              |                   |
| name        | varchar(255) | NO   |     | NULL              |                   |
| create_time | timestamp    | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| phone       | char(20)     | YES  |     | NULL              |                   |
+-------------+--------------+------+-----+-------------------+-------------------+
4 rows in set (0.00 sec)
-- 刪除列
ALTER TABLE User DROP COLUMN phone;

視圖

視圖是一張虛擬的表,不包含數據,只包含使用時動態檢索數據的查詢。

為什么使用視圖:

  • 重用SQL語句
  • 簡化復雜的SQL操作
  • 只是用表的一部分而不是整個表
  • 保護數據,可以授予用戶訪問表的特定部分的權限,而不是整個表的訪問權限
  • 更改數據格式和表示

性能問題

視圖不包含數據,每次使用視圖時,都必須處理查詢執行時需要的所有檢索,如果使用多個聯結和過濾創立了復雜的視圖或嵌套了視圖,性能可能會下降的很厲害

視圖的規則和限制

  • 必須擁有唯一命名
  • 創建視圖的數目沒有限制
  • 必須擁有足夠的訪問權限
  • 可以嵌套,嵌套層數因DBMS而異
  • 許多DBMS禁止使用ORDER BY
  • 有些DBMS要求對所返回的所有列命名,如果是計算字段,需要使用別名
  • 有些DBMS把視圖作為只讀查詢
  • 有些DBMS允許創建這樣的視圖:不能進行導致行不再屬于視圖的插入或更新

創建視圖 CREATE VIEW

CREATE VIEW song_singer AS
SELECT songs.name AS song_name,
songs.link,
singer.name AS singer_name,
singer_type.type
FROM songs,singer,singer_type
WHERE songs.singer = singer.id AND
singer.type = singer_type.id;

創建視圖時可以使用格式化語句或計算字段

使用視圖

SELECT語句中的所有約束條件在視圖中都適用。

mysql> SELECT * FROM song_singer WHERE singer_name = "薛之謙";

存儲過程

存儲過程可以理解為保存一條或多條語句,將其視為批文件,也可以看作是編程語言中的函數

為什么使用存儲過程

  • 把處理分裝在一個易用的單元中,可以簡化操作
  • 由于不要求反復建立一系列處理步驟,從而保證了數據的一致性
  • 簡化對變動的管理存儲過程通常以編譯過的形式存儲,所以DBMS處理命令的工作較少,提高了性能
  • 存在一些只能用在單個請求中的SQL元素和特性,存儲過程可以使用他們編寫功能更強,更靈活的代碼
  • 存在一些只能用在單個請求中的SQL元素和特性,存儲過程可以使用他們編寫更強更靈活的代碼。

缺點

  • 不同DBMS的存儲過程語法不同,可移植性差
  • 編寫復雜

參考

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457548.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457548.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457548.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git 忽略 部分文件夾_git提交忽略某些文件或文件夾

記得第一次用 github 提交代碼&#xff0c;node_modules 目錄死活傳不上去&#xff0c;哈哈哈&#xff0c;后來才知道在 .gitignore 文件里設置了忽略 node_modules 目錄上傳。是的&#xff0c; .gitignore 文件就是設置那些你不想用 git 一起上傳的文件和文件夾。比如剛接觸到…

Ajax實現原理詳解

Ajax&#xff1a;Asynchronous javascript and xml&#xff0c;實現了客戶端與服務器進行數據交流過程。使用技術的好處是&#xff1a;不用頁面刷新&#xff0c;并且在等待頁面傳輸數據的同時可以進行其他操作。 這就是異步調用的很好體現。首先得了解什么是異步和同步的概念。…

SpringJDBC解析3-回調函數(update為例)

PreparedStatementCallback作為一個接口&#xff0c;其中只有一個函數doInPrepatedStatement&#xff0c;這個函數是用于調用通用方法execute的時候無法處理的一些個性化處理方法&#xff0c;在update中的函數實現&#xff1a; protected int update(final PreparedStatementCr…

python上下文管理器

DAY 23. python上下文管理器 Python 的 with 語句支持通過上下文管理器所定義的運行時上下文這一概念。 此對象的實現使用了一對專門方法&#xff0c;允許用戶自定義類來定義運行時上下文&#xff0c;在語句體被執行前進入該上下文&#xff0c;并在語句執行完畢時退出該上下文&…

勾股定理python思路_趣叮咚編程數學揭秘:為什么勾股定理a+b=c?

我們都知道&#xff1a;三角形3個外角之和360度可是誰知道為什么等于360度呢&#xff1f;其實利用編程制作動圖演繹了解啦&#xff1a;那勾股定理abc又是為什么呢&#xff1f;還有很多有趣的數學公式都可以演繹&#xff1a;圓的面積公式、圓周長...通過動圖演繹原來晦澀難懂的定…

System.InvalidOperationException : 不應有 Response xmlns=''。

xml如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <Response version"2"><datacash_reference>4700203048783633</datacash_reference><information>Failed to identify the card scheme of the supp…

Navicat Premium連接SQL Server

Navicat Premium連接SQL Server 步驟&#xff1a; 激活SQL Server 服務配置SQL Server網絡配置連接SQL Server 激活SQLServer服務 直接搜索 計算機管理 點 服務和應用程序&#xff0c; 點 SQL Server配置管理器&#xff0c; 雙擊第一個SQL Server服務 不出意外的話&#xf…

mysql 單標遞歸_MySql8 WITH RECURSIVE遞歸查詢父子集的方法

背景開發過程中遇到類似評論的功能是&#xff0c;需要時用查詢所有評論的子集。不同數據庫中實現方式也不同&#xff0c;本文使用Mysql數據庫&#xff0c;版本為8.0Oracle數據庫中可使用START [Param] CONNECT BY PRIORMysql 中需要使用 WITH RECURSIVE需求找到name為張三的孩子…

processon完全裝逼指南

一、引言 作為一名IT從業者&#xff0c;不僅要有扎實的知識儲備&#xff0c;出色的業務能力&#xff0c;還需要具備一定的軟實力。軟實力體現在具體事務的處理能力&#xff0c;包括溝通&#xff0c;協作&#xff0c;團隊領導&#xff0c;問題的解決方案等&#xff0c;這些能力在…

mysql在空閑8小時之后會斷開連接(默認情況)

調試程序的過程發現&#xff0c;在mysql連接空閑一定時間&#xff08;默認8小時&#xff09;之后會斷開連接&#xff0c;需要重新連接&#xff0c;也引發我對重連機制的思考。轉載于:https://www.cnblogs.com/ppzbty/p/5707576.html

selector多路復用_多路復用器Selector

Unix系統有五種IO模型分別是阻塞IO(blocking IO)&#xff0c;非阻塞IO( non-blocking IO)&#xff0c;IO多路復用(IO multiplexing)&#xff0c;信號驅動(SIGIO/Signal IO)和異步IO(Asynchronous IO)。而IO多路復用通常有select&#xff0c;poll&#xff0c;epoll&#xff0c;k…

解決svn log顯示no author,no date的方法之一

只要把svnserve.conf中的anon-access read 的read 改為none&#xff0c;也不需要重啟svnserve就行 sh-4.1# grep "none" /var/www/html/svn/pro/conf/svnserve.conf ### and "none". The sample settings below are the defaults. anon-access none轉載…

REST framework 權限管理源碼分析

REST framework 權限管理源碼分析 同認證一樣&#xff0c;dispatch()作為入口&#xff0c;從self.initial(request, *args, **kwargs)進入initial() def initial(self, request, *args, **kwargs):# .......# 用戶認證self.perform_authentication(request)# 權限控制self.che…

解決larave-dompdf中文字體顯示問題

0、使用MPDF dompdf個人感覺沒有那么好用&#xff0c;最終的生產環境使用的是MPDF&#xff0c;github上有文檔說明。如果你堅持使用&#xff0c;下面是解決辦法。可以明確的說&#xff0c;中文亂碼是可以解決的。 1、安裝laravel-dompdf依賴。 Packagist&#xff1a;https://pa…

mfc程序轉化為qt_小峰的QT學習筆記

我的專業是輸電線路&#xff0c;上個學期&#xff0c;我們開了一門架空線路設計基礎的課&#xff0c;當時有一個大作業是計算線路的比載&#xff0c;臨界檔距&#xff0c;弧垂最低點和安裝曲線。恰逢一門結課考試結束&#xff0c;大作業ddl快到&#xff0c;我和另外兩個同專業的…

MS SQL的存儲過程

-- -- Author: -- Create date: 2016-07-01 -- Description: 注冊信息 -- ALTER PROCEDURE [dbo].[sp_MebUser_Register]( UserType INT, MobileNumber VARCHAR(11), MobileCode VARCHAR(50), LoginPwd VARCHAR(50), PayPwd VARCHAR(50), PlateNumber VARCHAR(20), UserTr…

mysql 中 all any some 用法

-- 建表語句 CREATE TABLE score(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),SUBJECT VARCHAR(20),score INT);-- 添加數據 INSERT INTO score VALUES (NULL,張三,語文,81), (NULL,張三,數學,75), (NULL,李四,語文,76), (NULL,李四,數學,90), (NULL,王五,語文,81), (…

REST framework 用戶認證源碼

REST 用戶認證源碼 在Django中&#xff0c;從URL調度器中過來的HTTPRequest會傳遞給disatch(),使用REST后也一樣 # REST的dispatch def dispatch(self, request, *args, **kwargs):""".dispatch() is pretty much the same as Djangos regular dispatch,but w…

scrapyd部署_如何通過 Scrapyd + ScrapydWeb 簡單高效地部署和監控分布式爬蟲項目

來自 Scrapy 官方賬號的推薦需求分析初級用戶&#xff1a;只有一臺開發主機能夠通過 Scrapyd-client 打包和部署 Scrapy 爬蟲項目&#xff0c;以及通過 Scrapyd JSON API 來控制爬蟲&#xff0c;感覺 命令行操作太麻煩 &#xff0c;希望能夠通過瀏覽器直接部署和運行項目專業用…

最長上升子序列 (LIS算法(nlong(n)))

設 A[t]表示序列中的第t個數&#xff0c;F[t]表示從1到t這一段中以t結尾的最長上升子序列的長度&#xff0c;初始時設F [t] 0(t 1, 2, ..., len(A))。則有動態規劃方程&#xff1a;F[t] max{1, F[j] 1} (j 1, 2, ..., t - 1, 且A[j] < A[t])。 現在&#xff0c;我們仔細…