1. 程式人生 > >PostgreSQL自學筆記:8 查詢數據

PostgreSQL自學筆記:8 查詢數據

表達 varchar 選擇 參數 stars 添加數據 視圖 條件表達式 pri

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 查詢數據