56、【数据库技术】【MySQL】多表查询

2021-04-13  本文已影响0人  yscyber

1、多表查询概述

在关系型数据库的理论中,将两个集合XY分别看作两张表,将集合中的元素看作表中的一行数据,多表查询的基础就建立在多表的笛卡尔积之上。

-- 商品分类表
CREATE TABLE category (
c_id VARCHAR(10),
c_name VARCHAR(30) NOT NULL,
CONSTRAINT PRIMARY KEY pk_category (c_id)
);

-- 商品表
CREATE TABLE product (
p_id VARCHAR(10),
p_name VARCHAR(30) NOT NULL,
p_price DECIMAL(7,2) DEFAULT 0.00 NOT NULL,
p_flag TINYINT DEFAULT 0 NOT NULL, -- 是否上架标记:1表示上架、0表示下架
p_c_id VARCHAR(10) DEFAULT NULL,
CONSTRAINT PRIMARY KEY pk_product(p_id),
CONSTRAINT FOREIGN KEY fk_product_category (p_c_id) REFERENCES category (c_id) ON UPDATE RESTRICT ON DELETE RESTRICT
);

-- 插入示例数据
INSERT INTO category(c_id,c_name)
VALUES('c001','家电');

INSERT INTO category(c_id,c_name)
VALUES('c002','鞋服');

INSERT INTO category(c_id,c_name)
VALUES('c003','化妆品');

INSERT INTO category(c_id,c_name)
VALUES('c004','汽车');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p001','小米电视机',5000.00,1,'c001');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p002','格力空调',3000.00,1,'c001');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p003','美的冰箱',4500.00,1,'c001');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p004','篮球鞋',800.00,1,'c002');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p005','运动裤',200.00,1,'c002');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p006','T恤',300.00,1,'c002');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p007','冲锋衣',2000.00,1,'c002');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p008','神仙水',800.00,1,'c003');

INSERT INTO product(p_id,p_name,p_price,p_flag,p_c_id)
VALUES('p009','大宝',200.00,1,'c003');

2、纯“笛卡尔积”式查询

SELECT ······
FROM table_1_name,table_2_name,······,table_n_name;
SELECT *
FROM category,product;
MySQL-多表查询-纯笛卡尔积式查询

3、内连接查询

3.1、隐式内连接

SELECT table_name_1.field_1,table_name_2.field_1,······
FROM table_name_1,table_name_2,······
WHERE ······
SELECT t1.field_1,t2.field,······
FROM table_name_1 [AS] t1,table_name_2 [AS] t2
WHERE ······
-- 查询所有商品信息和对应的分类信息
SELECT *
FROM product,category
WHERE product.p_c_id=category.c_id;
-- 查询商品表的商品名称和价格,以及商品的分类信息
SELECT p.p_name AS name,p.p_price AS price,c.c_name AS category
FROM product AS p,category AS c
WHERE p.p_c_id=c.c_id;
-- 查询格力空调是属于哪一分类下的商品
SELECT p.p_name AS name,c.c_name AS category
FROM product AS p,category AS c
WHERE p.p_c_id=c.c_id
AND p.p_id='p002';

3.2、显式内连接

SELECT t1.field1,t2.field1,······
FROM table_name_1 [AS] t1 [INNER] JOIN table_name_2 [AS] t2,······
ON ······
WHERE ······
-- 查询所有商品信息和对应的分类信息
SELECT *
FROM product INNER JOIN category
ON product.p_c_id=category.c_id;
-- 查询鞋服分类下,价格大于500的商品名称和价格
SELECT p.p_name AS name,p.p_price AS price
FROM product AS p INNER JOIN category AS c
ON p.p_c_id=c.c_id
WHERE p.p_price>500
AND c.c_id='c002'; 

4、外连接查询

4.1、左外连接查询

SELECT ······
FROM left_table_name LEFT [OUTER] JOIN right_table_name
ON ······
······;
SELECT *
FROM category LEFT [OUTER] JOIN product
ON category.c_id=product.p_c_id;
MySQL-左外连接查询示例
-- 查询每个分类下的商品个数

SELECT category.c_name,COUNT(product.p_id)
FROM category LEFT [OUTER] JOIN product
ON category.c_id=product.p_c_id
GROUP BY category.c_id;

4.2、右外连接查询

SELECT ······
FROM left_table_name RIGHT [OUTER] JOIN right_table_name
ON ······
······;
SELECT *
FROM product RIGHT OUTER JOIN category
ON category.c_id=product.p_c_id;
MySQL-右外连接查询示例

5、子查询

1、WHERE型子查询:将子查询的结果,作为父查询的条件。用在父查询的WHERE子句中。
2、FROM型子查询:将子查询的结果,当作一张表,提供给父层查询使用。用在父查询的FROM子句中。
3、EXISTS型子查询:子查询的结果是“单列多行”,类似一个数组,一般作为父查询的INNOT IN的条件使用。
4、上述类型的各种组合。

5.1、子查询的结果作为查询条件(WHERE型)

SELECT ······
FROM ······
WHERE field_xx=(SELECT ······);
-- 查询价格最高的商品的信息

SELECT *
FROM product
WHERE p_price=(
SELECT MAX(p_price)
FROM product);

-- 查询小于平均价格的商品的信息
SELECT *
FROM product
WHERE p_price<(
SELECT AVG(p_price)
FROM product);

5.2、子查询的结果作为一张表(FROM型)

SELECT ······
FROM (SELECT ······) [AS] xx
WHERE ······
······;
-- 查询商品中,价格大于500的商品信息,包括商品名称、商品价格、商品所属分类名称

SELECT p.p_name,p.p_price,c.c_name
FROM product [AS] p INNER JOIN (SELECT c_id,c_name FROM category) [AS] c
ON p.p_c_id=c.c_id
WHERE p.p_price>500;

5.3、子查询结果是单列多行(EXISTS型)

SELECT ······
FROM ······
WHERE field_xx IN (SELECT ······)
······;
-- 查询价格小于2000的商品,来自于哪些分类(名称)

SELECT category.c_name
FROM category
WHERE category.c_id IN (
SELECT DISTINCT product.p_c_id
FROM product
WHERE product.p_price<2000);
上一篇下一篇

猜你喜欢

热点阅读