PostgreSQL自學筆記:8 查詢數據
8 查詢數據
8.1 基本查詢語句
select語句的基本格式是:
select {* | 字段1[,字段2,...]} [ from 表1,表2... [where 表達式] [group by <分組條件>] [having 條件表達式 [{操作 表達式}...]] [order by [排序條件]] [limit 行數 [offset 偏移量]] ] select [字段1,字段2,...,字段n] from [表或視圖] where [查詢條件];
先建表並插入數據:
create table fruits(
f_id char(10) not null,
s_id int,
f_name char(255) not null,
f_price decimal(8,2) not null,
primary key(f_id)
);
insert into fruits values(‘a1‘,101,‘蘋果‘,5.2),(‘b1‘,101,‘黑莓‘,10.2), (‘bs1‘,102,‘橙子‘,11.2),(‘bs2‘,105,‘甜瓜‘,8.2), (‘t1‘,102,‘香蕉‘,10.3),(‘t2‘,102,‘葡萄‘,5.3), (‘o2‘,103,‘椰子‘,9.2),(‘c0‘,101,‘櫻桃‘,3.2), (‘a2‘,103,‘杏子‘,2.2),(‘l2‘,104,‘檸檬‘,6.4), (‘b2‘,104,‘番茄‘,8.6),(‘m1‘,106,‘芒果‘,15.6), (‘m2‘,105,‘xbaby‘,3.6),(‘t4‘,107,‘xbababa‘,3.6), (‘m3‘,105,‘xxtt‘,11.6),(‘b5‘,107,‘xxxx‘,3.6);
+------+------+---------+---------+ | f_id | s_id | f_name | f_price | +------+------+---------+---------+ | a1 | 101 | 蘋果 | 5.20 | | a2 | 103 | 杏子 | 2.20 | | b1 | 101 | 黑莓 | 10.20 | | b2 | 104 | 番茄 | 8.60 | | b5 | 107 | xxxx | 3.60 | | bs1 | 102 | 橙子 | 11.20 | | bs2 | 105 | 甜瓜 | 8.20 | | c0 | 101 | 櫻桃 | 3.20 | | l2 | 104 | 檸檬 | 6.40 | | m1 | 106 | 芒果 | 15.60 | | m2 | 105 | xbaby | 3.60 | | m3 | 105 | xxtt | 11.60 | | o2 | 103 | 椰子 | 9.20 | | t1 | 102 | 香蕉 | 10.30 | | t2 | 102 | 葡萄 | 5.30 | | t4 | 107 | xbababa | 3.60 | +------+------+---------+---------+
8.2 單表查詢
8.2.1 查詢所有字段
select * from fruits;
select f_id,s_id,f_name,f_price from fruits;
8.2.2 查詢指定字段
select 字段1[,字段2,...] from 表名;
select f_name from fruits;
select f_name,f_price from fruits;
8.2.3 查詢指定記錄
select 字段1[,字段2,...] from 表名 where 查詢條件;
select f_name,f_price from fruits where f_price > 10;
where字節判斷符:
- = <> != < <= > >=
between and
in not in
like : 模糊查找(通配符‘%‘)
is null : 空值
and
or
8.2.7 空值查詢
創建數據表的時候,設計者可以指定某列是否可以包含空值null.
空值不同於0,也不同於空字符串.空值一般表示數據未知
不適用或將在以後添加數據.在select語句中可以使用 is null
子句查詢某字段內容為空記錄
8.2.10 查詢結果不重復
select distinct 字段名 from 表名;
select distinct s_id from fruits;
8.2.11 對查詢結果排序
order by 字段1[,字段2,...] [ASC | DESC]
select f_name,f_price from fruits
order by f_name,f_price desc;
8.2.12 分組查詢
group by 字段1[,字段2,...] [having 條件表達式]
group by 通常和集合函數一起使用,例如
max() min() count() sum() avg()
- having與where都是用來過濾數據,區別:
having用在數據分組之後進行過濾,
where在分組之前用來選擇記錄,
另外where排除的記錄不再包括在分組中
select s_id,count(*) as total from fruits
group by s_id;
select s_id,count(f_name) from fruits
group by s_id having count(f_name) > 1;
select s_id,count(f_name) from fruits
group by s_id having count(f_name) > 1
order by count(f_name);
- cookie:
在MySQL中可以寫成
select s_id,count(f_name) as c from fruits group by s_id having c > 1;
PostgreSQL會報錯字段‘c‘不存在
8.2.13 用limit現在查詢結果的數量
limit 行數 [offset 偏移量]
select * from fruits
order by f_price ASC
limit 3 offset 2;
8.3 使用集合函數查詢
count() 計數
select count(*) as c from fruits;
- sum() 求和
select sum(f_price) as s from fruits
where s_id = 101;
- avg() 平均數
select avg(f_price) as s from fruits
where s_id = 101;
- max() 最大
select max(f_price) as s from fruits;
- min() 最小
select max(f_price) as s from fruits;
8.4 連接查詢
8.4.1 內連接查詢
inner join
先創建表suppliers並插入數據
create table suppliers(
s_id int primary key,
s_name varchar(50) not null,
s_city varchar(50) not null
);
insert into suppliers
values(101,‘周通‘,‘天津‘),(102,‘張良宇‘,‘上海‘),
(103,‘蔡宇航‘,‘北京‘),(104,‘彭田傑‘,‘鄭州‘),
(105,‘金鑫‘,‘新疆‘),(106,‘雷統江‘,‘九江‘),
(107,‘邵鵬飛‘,‘武漢‘);
select suppliers.s_id,s_name,f_name,f_price from fruits,suppliers
where fruits.s_id = suppliers.s_id;
select suppliers.s_id,s_name,f_name,f_price from fruits
inner join suppliers on fruits.s_id=suppliers.s_id;
8.4.2 外連接查詢
- left join(左連接)
返回包括左表中所有記錄和右表中連接字段相等的記錄 - right join(右連接)
返回包括右表中所有記錄和左表中連接字段相等的記錄
select suppliers.s_id,s_name,f_name,f_price from fruits
left join suppliers on fruits.s_id = suppliers.s_id;
select suppliers.s_id,s_name,f_name,f_price from suppliers
right join fruits on fruits.s_id = suppliers.s_id;
- 註:
當兩表中有相同的字段,就需要用完全限定表名,格式為"表名.列名"
8.4.3 復合條件連接查詢
select suppliers.s_id,s_name,f_name,f_price from fruits
inner join suppliers on fruits.s_id = suppliers.s_id
order by f_price;
8.5 子查詢
8.5.1 帶any,some關鍵字的子查詢
any和some關鍵字是同義詞,表示滿足其中任一條件
先建表tb11 tb12並插入數據
create table tb11(num1 int not null);
create table tb12(num2 int not null);
insert into tb11 values(1),(3),(5),(99);
insert into tb12 values(2),(4),(8),(16);
select num1 from tb11 where num1 > any (
select num2 from tb12
);
+------+
| num1 |
+------+
| 3 |
| 5 |
| 99 |
+------+
8.5.2 帶all關鍵字的子查詢
使用all關鍵字時需要滿足所有內層查詢條件
select num1 from tb11 where num1 > all (
select num2 from tb12
);
+------+
| num1 |
+------+
| 99 |
+------+
8.5.3 帶exists關鍵字的子查詢
exists關鍵字後面的參數是一個任意的子查詢,系統對子查詢進行計算以
判斷它是否返回行.如果至少返回一行,那麽exists的結果為true,此
時外層查詢語句進行查詢;如果子查詢沒有返回任何行,那麽exists
返回結果為false,此時外層語句將不進行查詢
select * from fruits where f_price >10.2 and exists
(select s_name from suppliers where s_id=107);
8.5.4 帶in關鍵字的子查詢
利用in關鍵字進行子查詢時,內層查詢語句僅僅返回一個數據列,這個數據
列裏的值將提供給外層查詢語句進行比較操作
先創建表customers並插入數據
create table customers(
c_id char(10) primary key,
c_name varchar(255) not null,
c_emil varchar(50) null
);
insert into customers
values(‘10001‘,‘RedHook‘,‘[email protected]‘),
(‘10002‘,‘Stars‘,‘[email protected]‘),
(‘10003‘,‘RedHook‘,null),
(‘10004‘,‘JOTO‘,‘sam$hotmail.com‘);
再創建表orders並插入數據
create table orders(
o_num int null,
o_date date not null,
c_id varchar(50) not null
);
insert into orders
values(30001,‘2018-09-01 00:00:00‘,‘10001‘),
(30002,‘2018-09-12 00:00:00‘,‘10003‘),
(30003,‘2018-09-30 00:00:00‘,‘10004‘),
(null,‘2018-10-03 00:00:00‘,‘10002‘),
(30004,‘2018-10-03 00:00:00‘,‘null‘),
(30005,‘2018-10-08 00:00:00‘,‘10001‘);
select o_num from orders where c_id in (
select c_id from customers where c_name=‘RedHook‘
);
8.5.5 帶比較運算符的子查詢
< = >= <= != <>
select s_id f_name from fruits where s_id <> (
select s1.s_id from suppliers as s1
where s1.s_city = ‘天津‘
);
8.6 合並查詢
利用union關鍵字,可以給出多條select語句,並將它們的結果組合成
單個結果集.合並時,兩個表對應的列數和數據類型必須相同.各
個select語句之間使用 union或 union all關鍵字分隔.union
不使用all,執行的時候刪除重復的記錄,返回的行都是唯一的;使
用關鍵字all的作用是不刪除重復行也不對結果進行自動排序
select 字段1[,字段2,...] from 表1
union [all] select 字段1[,字段2,...] from 表2;
select s_id,f_name,f_price from fruits where f_price < 9
union select s_id,f_name,f_price from fruits
where s_id in (101,103);
8.7 為表和字段取別名
8.7.1 為表取別名
表名 [as] 表別名
select * from orders as o where o.o_num=30001;
8.7.2 為字段取別名
列名 [as] 列別名
select f1.f_name as fn, f1.f_price as fp
from fruits as f1 where f1.f_price <8;
8.8 使用正則表達式查詢
PostgreSQL中正則表達式的操作符使用方法如下:
- ~ 匹配正則表達式,區分大小寫
- ~* 匹配正則表達式,不區分大小寫
- !~ 不匹配正則表達式,區分大小寫
- !~ 不匹配正則表達式,不0區分大小寫
8.8.1 查詢以特定字符或字符串開頭的記錄 ^
select * from fruits where f_name ~ ‘^x‘;
- cookie:
MySQL中正則語法與PostgreSQL略有不同,關鍵字是regexp
select * from fruits where f_name regexp ‘^x‘;
8.8.3 用‘.‘符號代替字符串中的任意一個字符
select * from fruits where f_name ~ ‘.子‘;
**8.8.4 使用‘*‘和‘+‘匹配多個字符**
‘*‘匹配前面的字符任意次,‘+‘匹配前面字符至少一次
select * from fruits where f_name ~ ‘ba*‘;
8.8.5 匹配指定字符串
匹配多個字符串時,多個字符串之間使用分隔符‘|‘隔開
select * from fruits where f_name ~ ‘子‘;
8.8.6 匹配指定字符中的任意一個 []
select * from fruits where f_name ~ ‘[果子]‘;
8.8.7 匹配指定字符以外的字符 !~
select * from fruits where f_name !~ ‘[果子]‘;
8.8.8 使用{M}或者{M,N}指定字符串連續出現的次數
‘字符串{n,m}‘,表示匹配前面的字符不少於n次,不多於m次
select * from fruits where f_name ~ ‘x{2,}‘;
PostgreSQL自學筆記:8 查詢數據