關係數據庫標準語言SQL入門

關係數據庫標準語言SQL

3.1 SQL概述

3.1.2 SQL的特點

  • 高度非過程化

  • 功能完並且一體化

  • 統一的語法結構

  • 語言簡潔,易學易用

    ​ 數據查詢:SELECT

    ​ 數據定義:CREATE,DROP

    ​ 數據操作:INSERT,UPDATE,DELETE

    ​ 數據控制:GRANT,REVOKE

3.2 SQL的定義功能

3.2.1基本表的定義

1.表結構的定義
CREATE TABLE<表名>
(<列名><數據類型>[列表完整性約束條件]
 [,<列名><數據類型>[列表完整性約束條件]···]
 [,<表級完整性約束條件>]
);
  • 表名是所要定義的基本表的名字,表可以由一個或多個屬性(列)組成
  • 定義表的各個列時需要指明其數據類型及長度
SQL 92提供的主要數據類型
類型 數據類型舉例及縮寫 說明
Binary BLOB 以十六進制格式存儲二進制字符串的值
BitString BIT(n)
BIT VARYING(n)
這兩種數據類型可以存儲二進制和十六進制數據
Boolean BOOLEAN true、false或unknow
Character CHAR(n)
VARCHAR(n)
存儲適宜的字符集中的任意字符組合
Numeric INTEGER
SMALLINT
DECIMAL(i,j)
FLOAT(p,s)
REAL
DOUBLE PERCISION
這些數據類型存儲數據的準確值(整數或小數)或近似值
Temporal DATE
TIME
TIMESTAMP
INTERVAL
這些數據類型處理時間的值
  • 完整性約束條件:Primary Key Foreign Key

【例3-1】

CREATE TABLE 學生
(學號 char(8) NOT NULL UNIQUE,
 姓名 char(8),
 性別 char(2),
 出生年份 SMALLINT,
 籍貫 char(8),
 學院 char(15));
2.主關鍵詞的定義
(1)在列出關係模型的屬性時,在屬性及其類型後加上保留字PRIMARY KEY
(2)在列出關係模型的所有屬性後,再附加一個聲明:
PRIMARY KEY(<屬性1>[,<屬性2>,···])

【例3-2】

  • 方法一
CREATE TABLE 學生
(學號 char(8) PRIMARY KEY,
 姓名 char(8),
 性別 char(2),
 出生年份 SMALLINT,
 籍貫 char(8),
 學院 char(15));
  • 方法二
CREATE TABLE 學生
(學號 char(8),
 姓名 char(8),
 性別 char(2),
 出生年份 SMALLINT,
 籍貫 char(8),
 學院 char(15)
 PRIMARY KEY(學號));

【例3-3】

CREATE TABLE 課程
(課程號 SMALLINT NOT NULL UNIQUE,
 課程名 char(15),
 學時  SMALLINT,
 開課學期 char(4),
 課程性質 char(15),
 primary key(課程號));

【例3-4】

CREATE TABLE 學習
(學號 char(8),
 課程號 char(8),
 成績 smallint,
 primary key(學習,課程號));
3. 外部關鍵字的定義
(1)如果外部關鍵詞只有一個屬性,可以在它的屬性名和類型後面直接用REFERENCES說明它參照了某個表的某些屬性(必須是PRIMARY KEY
REFERENCES <表名> (<屬性>)
(2) 在屬性列後面添加
FOREIGN KEY(<屬性 1>REFERENCES<表名>(<屬性2>))

【例3-5】

CREATE TABLE 學習
(學號 char(8),
 課程號 char(8),
 成績 smallint,
 primary key(學習,課程號)
 FOREIGN KEY(學號 references 學生(學號))
 FOREIGN KEY(課程號 references 課程(課程號));
4.默認值的定義
性別 char(2) default '男';
年齡 smallint default 19;

3.2.2 基本表的修改和刪除

ALTER TABLE 學生 ADD COLUMN 年齡 SMALLINT;

ALTER TABLE 課程 ALTER COLUMN 課程名 CHAR(20);

ALTER TABLE 學生 DROP COLUMN 年齡;

DROP TABLE <表名>

3.2.3 索引的建立和刪除

3.3 數據查詢

SELECT [ALL|DISTINCT]<屬性列表>
FROM <表名或視圖名>[,[表名或視圖名]]···
[WHERE <條件表達式>]
[GROUP BY <列名>]
[HAVING <條件表達式>]
[ORDER by<列名>[]];

3.3.1 單表查詢

  • 選擇表中的若干列(投影)
  • 選擇表中的若干元組(選擇)
  • 對查詢進行分組
  • 使用集函數
  • 對查詢結果排序
1.SQL中的投影

【例3-12】

SELECT 姓名,籍貫
FROM 學生;

【例3-13】

SELECT DISTINCT 籍貫
FROM 學生;

【例3-14】

SELECT *
FROM 學生;

【例3-15】

查詢學生學號和年齡

select 學號,year(now())-出生年份
from 學生;

【例3-16】

給列表別名

select 學號,year(now())-出生年份 as 年齡
from 學生;
2. SQL中的選擇運算
常用的查詢條件
查 詢 條 件 謂 詞
比較 =, <>, >, <, >=, <=
算數運算 +,-,*,/
確定範圍 BETWEEN AND, NOT BETWEEN AND
確定集合 IN, NOT IN
字符匹配 LIKE, NOT LIKE
空值 IS NULL, IS NOT NULL
多重條件 AND,OR
1)比較運算

【例3-17】

查詢所有不及格課程的學生的學號,課程號及成績

select 學號,課程號,成績
from 學習
where 成績<60;

【例3-18】

查詢有不及格課程的學生的學號

select distinct 學號
from 學習
where 成績<60;
2)多重運算和算術運算

【例3-19】

在學生表中找出信電學院2000年後出生的學生的記錄

select *
from 學生
where 學院='信電' and 出生年份>2000;
3)確定範圍

【例3-20】

select 姓名,性別,學院,出生年份
from 學生
where 出生年份 between 1996 and 1998;
4)確定集合

【例3-21】

select 學號,姓名,出生年份
from 學生
where 學院 in ('信電','理學院','計算機');
5)字符匹配
[not] like '<匹配串>' [ESCAPE'<轉碼字符>']
6)空值
3.對查詢結果進行分組
select 課程號,count(學號) as 選課人數
from 學習
group by 課程號;

【例3-27】

select 學號,count(課程號) as 選修課程數
from 學習
where 學號 between '091501' and '091506' 
group by 學號
having 選修課程數>3;
4.使用集函數
COUNT([DISTINCT|ALL]*) #統計原則個數
COUNT([DISTINCT|ALL]<列名>)#統計一列中值的個數
SUM([DISTINCT|ALL]<列名>)#計算一列值的總和
AVG([DISTINCT|ALL]<列名>)#平均值
MAX([DISTINCT|ALL]<列名>)#最大值
MIN([DISTINCT|ALL]<列名>)#最小值
#查詢學生總人數
select count(*)
from 學生; 

#查詢計算機學院學生的平均年齡
select avg(year(now())-出生年份) as 平均年齡 #別忘了別名
from 學生
where 學院='計算機';

#查詢學習180101號課程的學生最高分數
select max(成績) as 最高分
from 學習
where 課程號='180101'
5.對查詢結果排序
select 學號,成績
from 學習
where 課程='180102'
order by 成績 desc;

查詢全體學生情況,查詢結果按所在學院的名稱升序排列,對同一學院中給的學生按年齡降序排列

select *
from 學生
order by 學院 asc, year(now())-出生年份 desc;

3.3.2 連接查詢

  • 等值連接和非等值連接
  • 自身連接查詢
  • 外連接查詢
  • 複合條件連接查詢
  • 集合運算查詢

(1)ANSI 方式

【例3-33】

#查詢每個學生及其選修課程的情況
select 學生.*,學習.*
from 學生 INNER JOIN 學生.學號=學習.學號;

(2) theta方式

select 學生.*,學習.*
from 學生,學習
where 學生.學號=學習.學號;
1.等值與非等值連接查詢
[<表名1>.]<列名1><比較運算符>[<表名2>.]<列名> #比較運算符爲=時爲等值連接
#自然連接“學生表”和“學習表”
select 學生.學號,姓名,性別,出生年份,學院,課程號,成績
from 學生,學習
where 學生.學號=學習.學號
2.自身連接查詢
#求一門課程的間接先修課
select first.課程號 as 課程號,first.課程名 as 課程名,second.課程名 as 間接選修課
from 課程 as first,課程 as second
where first.先修課課程號=second.課程號;
3. 外連接查詢
1)左外連接

規定所有記錄都應該從連接語句左側的表中返回。當右側表中沒有匹配的記錄時,左表中該記錄依然會返回,而右側表中的列值將自動填充NULL 值

#查詢所有學生的姓名以及他們選修課程的課程號和成績
select 姓名,課程號,成績
from 學生,學習
where 學生.學號(+)=學習.學號;
2) 右外連接

規定所有記錄都應該從連接語句右側的表中返回。當右側表中沒有匹配的記錄時,左表中該記錄依然會返回,而右側表中的列值將自動填充NULL 值

4.複合條件連接查詢
#查詢選修180101號課程且成績在90分以上的學生學號,姓名以及成績
select 學生.學號,姓名,成績
from 學生,學習
where 學生.學號=學習.學號
and 課程號='180101'
and 成績>90;

#ANSI
select 學生.學號,姓名,成績
from 學生 JOIN on 學生.學號=學習.學號
and 課程號='180101'
and 成績>90;

#查詢每個學生及其選修的課程名及其成績
select 學生.學號,姓名,課程名,成績
from 學生,課程,學習
where 學生.學號=學習.學號
and 學習.課程號=課程.課程號;

#ANSI
select 學生.學號,姓名,課程名,成績
from 學生
  JOIN  學習 on 學生.學號=學習.學號
  JOIN  課程 on 學習.課程號=課程.課程號;
5.集合運算連接查詢
  • 並:UNION
  • 交:INTERSECT
  • 差:EXCEPT
#查詢選修了180101號或180102號課程或二者都選修了的學生學號、課程號和成績
(select 學生.學號,課程號,成績
 from 學生,學習
 where 學生.學號=學習.學號 and 課程號='180101')
 union
 (select 學生.學號,課程號,成績
 from 學生,學習
 where 學生.學號=學習.學號 and 課程號='180102')

3.3.3 嵌套查詢

  • 相關子查詢
  • 不相關子查詢
1. 帶有IN謂詞的子查詢
#查詢選修了“數據庫原理”課程的學生學號和姓名
select 學號,姓名
from 學生
where 學號 in
(select 學號
 from 學習
 where 課程號 in
(select 課程號
 from 課程
 where 課程名='數據庫原理'));
 
#用IN來實現交運算,大部分DBMS不支持INTERSECT
 SELECT 學號,課程號,成績
 from 學習
 where 課程號='180101' and 學號 in
 (select 學號
  from 學習
  where 課程號='180102' )
  
#NOT IN 差運算
 SELECT 學號,課程號,成績
 from 學習
 where 課程號='180101' and 學號 not in
 (select 學號
  from 學習
  where 課程號='180102' )
2.帶有比較運算符的查詢
3.帶有ANY或ALL謂詞的子查詢
#查詢其他學院比計算機學院某個學生年齡小的學生名單
select 姓名
from 學生
where year(now())-出生年份 < ANY
(select year(now())-出生年份
 from 學生
 where 學院='計算機')
 and 學院!='計算機'
 order by year(now())-出生年份 desc;
4.帶有EXISTS謂詞的子查詢
#EXISTS實現交運算
SELECT s1.學號,s1.課程號,s1.成績
from 學習 as s1
where s1.課程號='180101' and exists
(select *
 from 學習 as s2
 where s2.課程號='180102' and s1.學號=s1.學號);
 
#EXISTS實現差運算
SELECT s1.學號,s1.課程號,s1.成績
from 學習 as s1
where s1.課程號='180101' and not exists
(select *
 from 學習 as s2
 where s2.課程號='180102' and s1.學號=s1.學號);

:¬(BA) 除運算 :\lnot(B-A)

#選修過全部課程的學生的學號和姓名
select 學號,姓名
from 學生
where not exists
(select *
 from 課程
 where not exists
 (select *
  from 學習
  where 學習.學號=學生.學號 and 學習.課程號=課程.課程號 )
)
#查詢至少選修了091501號學生選修的全部課程的學生學號
select 學號
from 學生
where not exists
(select *
 from 學習 as First
 where First.學號='091501' and not exists
 (select *
  from 學習 as Second
  where Second.學號=學生.學號 and Second.課程號=First.課程號))

3.4 數據更新

  • 插入
  • 刪除
  • 修改

3.4.1 插入數據

1.插入單個元組
INSERT 
INTO <表名> [<屬性列>]
Values (<常量1>[,<常量2>···])
INSERT INTO 學習(學號,課程號)
VALUES('091530','080102')
2.插入子查詢結果
INSERT
INTO <表名> [<屬性列>]
子查詢;
#統計每門課的平均分
CREATE TABLE 課程平均分
(課程號 CHAR(8)
 課程名 CHAR(15)
 平均分 DOUBLE);
INSERT 
  INTO 課程平均分(課程號,課程名,平均分)
     SELECT 課程號,課程名,AVG(成績)
     FROM 課程,學習
     WHERE 課程.課程號=學習.課程號
     GROUP BY 課程號,課程名; 

3.4.3修改數據

UPDATE <表名>
SET <列名>=<表達式>
[WHERE <條件>];
1.更改表中一個元組
UPDATE 學生
SET 籍貫='江蘇'
WHERE 學號='091611';
2.更新表中多個元組的數據
#將180101號課程的成績增加一分
UPDATE 學習
SET 成績=成績+1
WHERE 課程號='180101';
3.帶子查詢的修改
UPDATE 學習
SET 成績=0
WHERE 學號 IN
(SELECT 學號
 FROM 學生
 WHERE 學院='計算機');

3.5 視圖

視圖
概念:視圖是從一個或幾個基本表或視圖導出的表
視圖也稱爲虛表或虛關係:只存放視圖的定義
視圖時一種外模式,從一定程度上提高了視圖的安全性

3.5.1 建立視圖

create view <視圖名>[(<列名>)]
as <子查詢>
[WITH CHECK OPTION];

WITH CHECK OPTION表示對視圖進行插入、刪除和更新操作時要保證發生變動的行慢則視圖定義中的謂詞條件(即子查詢中的條件)

#建立計算機學院選修了“數據庫原理”這門課的學生的視圖
CREATE VIEW DB_S1
AS
SELECT 學生,學號,姓名,籍貫,學院,成績
FROM 學習,學生,課程
WHERE 學院='計算機'AND學生.學號=學習.學號 AND 學習.課程號=課程.課程號 and 課程名='數據庫原理'

#定義一個反映學生年齡的視圖
CREATE VIEW BT_S(學號,姓名,年齡)
as
SELECT 學號,姓名,year(now())-出生年份 AS 年齡
FROM 學生
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章