多表數(shù)據(jù)聯(lián)合查詢
?專欄內(nèi)容:
- postgresql內(nèi)核源碼分析
- 手寫數(shù)據(jù)庫toadb
- 并發(fā)編程
?開源貢獻(xiàn):
- toadb開源庫
個人主頁:我的主頁
管理社區(qū):開源數(shù)據(jù)庫
座右銘:天行健,君子以自強(qiáng)不息;地勢坤,君子以厚德載物.
系列文章
- 入門準(zhǔn)備
- postgrersql基礎(chǔ)架構(gòu)
- 快速使用
- 初始化集群
- 數(shù)據(jù)庫服務(wù)管理
- psql客戶端使用
- pgAdmin圖形化客戶端
- 數(shù)據(jù)庫的使用
- 創(chuàng)建數(shù)據(jù)庫
- 數(shù)據(jù)庫操作
- 表的使用
- 表的創(chuàng)建
- 表的操作
- 數(shù)據(jù)查詢
- 數(shù)據(jù)查詢
- 多表聯(lián)合查詢
- 數(shù)據(jù)操作
- 插入數(shù)據(jù)的方式
前言
postgresql 數(shù)據(jù)庫是一款通用的關(guān)系型數(shù)據(jù),在開源數(shù)據(jù)庫中能與商業(yè)數(shù)據(jù)媲美,在業(yè)界也越來越流行。
因為是開源數(shù)據(jù)庫,不僅公開源碼,還有很多使用案例,好用的插件,所以它的慢慢變成了數(shù)據(jù)庫的先驅(qū)和標(biāo)準(zhǔn),通過postgresql可以很好從使用到原理,徹底搞懂;
如果是學(xué)習(xí)編程,也可以學(xué)到豐富的編程知識,數(shù)據(jù)結(jié)構(gòu),編程技巧,它里面還有很多精妙的架構(gòu)設(shè)計,分層思想,可以靈活定制的思想。
本專欄主要介紹postgresql 入門使用,數(shù)據(jù)庫維護(hù)管理,通過這些使用來了解數(shù)據(jù)庫原理,慢慢了解postgresql是什么樣的數(shù)據(jù)庫,能做那些事情,以及如何做好服務(wù),最關(guān)鍵的是這些知識都是面試的必備項。
概述
我們在實際應(yīng)用中查詢數(shù)據(jù),往往涉及到多表的數(shù)據(jù),如何使用一條SQL就能得到結(jié)果呢?
本文就來分享一下,多表數(shù)據(jù)的查詢方法,并舉例說明它們使用的技巧;
原理介紹
多表數(shù)據(jù)的聯(lián)合查詢,在postgresql 中有兩個基本方法:
- join 連接操作;
- union 聯(lián)合子查詢;
多表join連接,其實就是通過某個列作為紐帶,將多個實際的表連接成一張大表,然后在大表上進(jìn)行查詢;
而union 與 join 完全不同, union 通過聯(lián)合 多個子查詢結(jié)果,也就是說union 操作的是查詢結(jié)果,將多個結(jié)果集合并成一個結(jié)果集,然后在這個總結(jié)果集上再進(jìn)行二次查詢處理;
也就是我們數(shù)學(xué)中的集合的幾種
而更加總結(jié)的話,就涉及到關(guān)系代數(shù)中對于集合的操作:
集合操作主要包括以下幾種:
- 并集操作(Union):將兩個集合合并成一個集合,包括所有屬于兩個集合的元素。
- 交集操作(Intersection):將兩個集合的公共元素組成一個新的集合。
- 差集操作(Difference):從一個集合中去掉屬于另一個集合的元素,剩下的元素組成一個新的集合。
- 對稱差集操作(Symmetric Difference):將屬于一個集合但不屬于另一個集合的元素,以及屬于另一個集合但不屬于一個集合的元素組成一個新的集合。
- 笛卡爾積操作(Cartesian Product):將兩個集合的所有可能有序?qū)M成一個新的集合。
多表 join 連接操作
在PostgreSQL中,多表查詢是通過使用連接(JOIN)和交叉連接(CROSS JOIN)等操作來實現(xiàn)的。
連接操作是指將兩個或多個表按照指定的條件進(jìn)行關(guān)聯(lián),以獲得它們之間的關(guān)系數(shù)據(jù)。
下面我們舉例來說明,首先創(chuàng)建兩張表custom 和 order;
以下是一個使用PostgreSQL進(jìn)行JOIN操作的案例:
假設(shè)我們有兩個表:customers
和orders
。customers
表包含客戶的信息,而orders
表包含訂單的信息。這兩個表通過一個共同的字段customer_id
相關(guān)聯(lián)。
首先,讓我們創(chuàng)建這兩個表并插入一些數(shù)據(jù):
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(50)
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
total_amount DECIMAL(10,2)
);
INSERT INTO customers (customer_id, name, email)
VALUES (1, 'John Doe', 'john@example.com'),
(2, 'Jane Smith', 'jane@example.com'),
(3, 'Bob Johnson', 'bob@example.com'),
(4, 'Steven John', 'steven@example.com'),
(5, 'Kenidy', 'Kenidy@example.com');
INSERT INTO orders (order_id, customer_id, order_date, total_amount)
VALUES (1, 1, '2023-01-01', 100.00),
(2, 1, '2023-02-01', 200.00),
(3, 2, '2023-02-15', 150.00),
(4, 3, '2023-03-01', 75.00);
1. 內(nèi)連接(INNER JOIN)
將兩個表中的行進(jìn)行匹配,返回滿足連接條件的行。語法如下:
postgres=# SELECT * FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id;
customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------
1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.00
1 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.00
2 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.00
3 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
這里特意用 *
查出結(jié)果集中的所有列,讓我們可以清晰看到結(jié)果集的全貌,可以看到j(luò)oin后的結(jié)果集,是兩表的所有列的合并;
對于內(nèi)聯(lián)連,只是列出了符合連接條件的行,大家想一想,還有什么寫法可以達(dá)到這種效果 。
對于, 條件寫到where子句中也可以,所以內(nèi)聯(lián)接與where條件是等價的;
postgres=# select * from customers,orders where customers.customer_id = orders.customer_id;
customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------
1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.00
1 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.00
2 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.00
3 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
2. 左連接(LEFT JOIN)
在內(nèi)連接的基礎(chǔ)上,將左側(cè)表中的所有行都包含在結(jié)果集中,即使右側(cè)表中沒有匹配的行。語法如下:
postgres=# select * from customers left join orders on customers.customer_id = orders.customer_id;
customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+--------------------+----------+-------------+------------+--------------
1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.00
1 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.00
2 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.00
3 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
5 | Kenidy | Kenidy@example.com | | | |
4 | Steven John | steven@example.com | | | |
(6 rows)
左聯(lián)接后的結(jié)果集,列也是兩表的合并,而行數(shù)與之前不同,左邊表列表出所有行,而右邊的表只列出了符合條件的行,對于左表多出的行,右表以空代替;
3. 右連接(RIGHT JOIN)
在內(nèi)連接的基礎(chǔ)上,將右側(cè)表中的所有行都包含在結(jié)果集中,即使左側(cè)表中沒有匹配的行。語法如下:
postgres=# select * from customers right join orders on customers.customer_id = orders.customer_id;
customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------
1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.00
1 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.00
2 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.00
3 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
右聯(lián)接與左聯(lián)接類似,結(jié)果集的行包括右表的所有行,左表只有符合聯(lián)接表條件行;
4. 全連接(FULL JOIN)
相當(dāng)于在左連接和右連接的基礎(chǔ)上,同時做左連接和右連接,并返回兩側(cè)表中所有滿足條件的行。語法如下:
postgres=# select * from customers full join orders on customers.customer_id = orders.customer_id;
customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+--------------------+----------+-------------+------------+--------------
1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.00
1 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.00
2 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.00
3 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
5 | Kenidy | Kenidy@example.com | | | |
4 | Steven John | steven@example.com | | | |
(6 rows)
全聯(lián)接就是包括左右兩條的所有行,沒有符合條件的行以空代替;
多表union 操作
PostgreSQL中的聯(lián)合查詢是一種將多個SELECT語句的結(jié)果組合成一個結(jié)果集的方法。它允許您從多個表或查詢中獲取數(shù)據(jù),并根據(jù)指定的條件將它們組合在一起。
聯(lián)合查詢的基本語法如下:
SELECT column1, column2, ...
FROM table1
UNION/UNION ALL/EXCEPT/INTERSECT
SELECT column1, column2, ...
FROM table2
WHERE condition;
這里有幾個關(guān)鍵部分:
-
SELECT
語句:用于指定要檢索的列和表。 -
UNION
、UNION ALL
、EXCEPT
和INTERSECT
:這些關(guān)鍵字用于指定要執(zhí)行的聯(lián)合操作類型。 -
WHERE
子句:可選的條件,用于篩選結(jié)果。
聯(lián)合類型說明
-
UNION
:返回兩個查詢結(jié)果的并集,但會刪除重復(fù)的行。 -
UNION ALL
:返回兩個查詢結(jié)果的并集,包括重復(fù)的行。 -
EXCEPT
:返回第一個查詢結(jié)果中存在但在第二個查詢結(jié)果中不存在的行。 -
INTERSECT
:返回兩個查詢結(jié)果中共有的行。
請注意,使用聯(lián)合查詢時,確保每個查詢中選擇的列數(shù)和列類型是一致的,否則可能會導(dǎo)致錯誤。
1. union
合并兩個表的數(shù)據(jù)并刪除重復(fù)行
postgres=# select customer_id from customers union select customer_id from orders ;
customer_id
-------------
2
3
5
4
1
(5 rows)
這將返回一個結(jié)果集,其中包含兩個表中所有不重復(fù)的行;
兩個select 子句中的列數(shù)和類型必須一致才行,這樣兩個結(jié)果集才能合并到一起。
2. union all
合并兩個表的數(shù)據(jù)并保留重復(fù)行
如果我們希望保留兩個表中的所有行,包括重復(fù)的行,那么可以使用 UNION ALL 運算符。
postgres=# select customer_id from customers union all select customer_id from orders ;
customer_id
-------------
1
2
3
4
5
1
1
2
3
(9 rows)
這將返回一個結(jié)果集,其中包含兩個表中所有的行,包括重復(fù)的行。
同時,如果想要對結(jié)果進(jìn)行排序;
可以使用 ORDER BY 子句。例如:
postgres=# select customer_id from customers union all select customer_id from orders order by customer_id asc;
customer_id
-------------
1
1
1
2
2
3
3
4
5
(9 rows)
當(dāng)然也可以加where 等其它子句;
3. except
獲得兩個集合的差,也就是前者集合中包括,而不屬于后者集合的行;
postgres=# select customer_id from customers except select customer_id from orders ;
customer_id
-------------
5
4
(2 rows)
也就是查詢還沒有產(chǎn)生訂單的客戶ID列表;
3. intersect
INTERSECT
運算符用于找出兩個SELECT
語句結(jié)果集的交集。它的語法如下:
postgres=# select customer_id from customers intersect select customer_id from orders order by customer_id asc;
customer_id
-------------
1
2
3
(3 rows)
這個類似于inner join,找到有訂單的客戶id列表;
總結(jié)
相同之處是,它們都是對結(jié)果集進(jìn)行操作;
但是有明顯的區(qū)別,join是將多表進(jìn)行聯(lián)接,產(chǎn)生結(jié)果集,然后再通過where等條件在聯(lián)接后的結(jié)果集上再過濾;
而union并不限于表與表之間,而是對不同查詢結(jié)果集,再進(jìn)行集合操作,而且對于最終結(jié)果的列有要求,必須參與的集合列數(shù)量和類型要相同;
結(jié)尾
非常感謝大家的支持,在瀏覽的同時別忘了留下您寶貴的評論,如果覺得值得鼓勵,請點贊,收藏,我會更加努力!
作者郵箱:study@senllang.onaliyun.com
如有錯誤或者疏漏歡迎指出,互相學(xué)習(xí)。文章來源:http://www.zghlxwxcb.cn/news/detail-713274.html
注:未經(jīng)同意,不得轉(zhuǎn)載!文章來源地址http://www.zghlxwxcb.cn/news/detail-713274.html
到了這里,關(guān)于【postgresql 基礎(chǔ)入門】多表聯(lián)合查詢 join與union 并,交,差等集合操作,兩者的區(qū)別之處的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!