-- 提示:文章本身就是一个sql脚本,可以直接执行。
-- 该文章参考了 http://lavasoft.blog.51cto.com/62575/38929/,对文章内容做了精简。
-- 文章主要针对MYSQL,目的是以简明的方式说明各种查询。
use test;
-- CUSTOEMRS 表现客户信息
-- ORDERS 表现客户所下订单信息,其中CUSTOMER_ID描述该订单为哪一个客户所下。
DROP TABLE IF EXISTS CUSTOMERS;
DROP TABLE IF EXISTS ORDERS;
CREATE TABLE CUSTOMERS (ID BIGINT NOT NULL,NAME VARCHAR(15) NOT NULL,AGE INT,
PRIMARY KEY (ID));
CREATE TABLE ORDERS (ID BIGINT NOT NULL,ORDER_NUMBER VARCHAR(15) NOT NULL,
PRICE DOUBLE PRECISION,CUSTOMER_ID BIGINT,PRIMARY KEY (ID));
-- ==================================================================================
INSERT INTO CUSTOMERS(ID,NAME,AGE) VALUES(1,'TOM',21);
INSERT INTO CUSTOMERS(ID,NAME,AGE) VALUES(2,'MIKE',24);
INSERT INTO CUSTOMERS(ID,NAME,AGE) VALUES(3,'JACK',30);
INSERT INTO CUSTOMERS(ID,NAME,AGE) VALUES(4,'LINDA',25);
INSERT INTO CUSTOMERS(ID,NAME,AGE) VALUES(5,'DAMA',NULL);  -- 大妈,年龄不详
-- =================================================================================
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(1,'TOM_ORDER001',100,1);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(2,'TOM_ORDER002',200,1);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(3,'TOM_ORDER003',300,1);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(4,'MIKE_ORDER001',100,2);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(5,'JACK_ORDER001',200,3);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID) VALUES(6,'LINDA_ORDER001',100,4);
INSERT INTO ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID)
VALUES(7,'不明订单',200,NULL); -- 该订单没有客户
-- 5号大妈没有下订单
-- ==================================================================================
-- 各种查询示例:
-- =================交叉连接====================================================
-- 隐式交叉连接,将会形成两个集合的迪卡尔积(请注意观察结果)
SELECT O.ID, O.ORDER_NUMBER, C.ID, C.NAME FROM ORDERS O , CUSTOMERS C ;
-- 显式交叉连接
SELECT O.ID, O.ORDER_NUMBER, C.ID, C.NAME FROM ORDERS O CROSS JOIN CUSTOMERS C ;
-- 该转接可以会形成一个m*n行的中间表,它无实际意义,但可以做为后面的查询的基础。
-- ===============================================================================
-- ===================内连接(观察结果)============================================
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME FROM CUSTOMERS C,ORDERS O WHERE C.ID=O.CUSTOMER_ID; -- 隐式
SELECT O.ID,O.ORDER_NUMBER, C.ID, C.NAME FROM ORDERS O
INNER JOIN CUSTOMERS C ON O.CUSTOMER_ID=C.ID; -- 显示
/*
+----+----------------+----+-------+
| ID | ORDER_NUMBER   | ID | NAME  |
+----+----------------+----+-------+
|  1 | TOM_ORDER001   |  1 | TOM   |
|  2 | TOM_ORDER002   |  1 | TOM   |
|  3 | TOM_ORDER003   |  1 | TOM   |
|  4 | MIKE_ORDER001  |  2 | MIKE  |
|  5 | JACK_ORDER001  |  3 | JACK  |
|  6 | LINDA_ORDER001 |  4 | LINDA |
+----+----------------+----+-------+
*/
-- 实质上对“交叉连接”的中间表进行了过滤(ON O.CUSTOMER_ID=C.ID),
-- 该查询描述出:每个下过订单的客户,所下订单的情况。注意:7号订单,5号客户并未出现在结果中。
-- ===================左外连接============================================================
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME FROM ORDERS O
LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
/*
+----+----------------+-------------+------+-------+
| ID | ORDER_NUMBER   | CUSTOMER_ID | ID   | NAME  |
+----+----------------+-------------+------+-------+
|  1 | TOM_ORDER001   |           1 |    1 | TOM   |
|  2 | TOM_ORDER002   |           1 |    1 | TOM   |
|  3 | TOM_ORDER003   |           1 |    1 | TOM   |
|  4 | MIKE_ORDER001  |           2 |    2 | MIKE  |
|  5 | JACK_ORDER001  |           3 |    3 | JACK  |
|  6 | LINDA_ORDER001 |           4 |    4 | LINDA |
|  7 | 不明订单                    |        NULL | NULL | NULL  |  --》多出的行
+----+----------------+-------------+------+-------+
*/
-- 观察结果:实质上是在内连接的基础上,增加了左表(ORDERS)中无法与右表相连的记录,如:7号记录。
-- ===========================================================================================
-- ===================右外连接================================================================
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME FROM ORDERS O
RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
/*
+------+----------------+-------------+----+-------+
| ID   | ORDER_NUMBER   | CUSTOMER_ID | ID | NAME  |
+------+----------------+-------------+----+-------+
|    1 | TOM_ORDER001   |           1 |  1 | TOM   |
|    2 | TOM_ORDER002   |           1 |  1 | TOM   |
|    3 | TOM_ORDER003   |           1 |  1 | TOM   |
|    4 | MIKE_ORDER001  |           2 |  2 | MIKE  |
|    5 | JACK_ORDER001  |           3 |  3 | JACK  |
|    6 | LINDA_ORDER001 |           4 |  4 | LINDA |
| NULL | NULL           |        NULL |  5 | DAMA  | --》多出的行
+------+----------------+-------------+----+-------+
*/
-- 观察结果:质上是在内连接的基础上,增加了右表(CUSTOMERS)中无法与左表相连的记录,如:5号记录。
-- =============================================================================================
-- ===================全外连接==================================================================
-- SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME FROM ORDERS O
FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
/*
+------+----------------+-------------+----+-------+
| ID   | ORDER_NUMBER   | CUSTOMER_ID | ID | NAME  |
+------+----------------+-------------+----+-------+
|    1 | TOM_ORDER001   |           1 |  1 | TOM   |
|    2 | TOM_ORDER002   |           1 |  1 | TOM   |
|    3 | TOM_ORDER003   |           1 |  1 | TOM   |
|    4 | MIKE_ORDER001  |           2 |  2 | MIKE  |
|    5 | JACK_ORDER001  |           3 |  3 | JACK  |
|    6 | LINDA_ORDER001 |           4 |  4 | LINDA |
|    7 | 不明订单       |        NULL  |NULL| NULL  |  --》多出的行
| NULL | NULL           |        NULL |  5 | DAMA  | --》多出的行
+------+----------------+-------------+----+-------+
*/
-- 观察结果:质上是在内连接的基础上,增加了右表(CUSTOMERS)中无法与左表相连的记录,
-- 如:5号记录,增加了左表(ORDERS)中无法与右表相连的记录,如:7号记录。。
-- 该连接在MySQL中是不支持的,只有对Oracle和SQL Server支持。