最近在处理商品表、属性表(一个商品可以有多个属性也可以没有属性)使用到了join,在此总结一下
1.left join(左连接) 返回左表中的所有记录和右表中关联字段相等的记录
2.right join(右连接) 返回右表中的所有记录和左表中关联字段相等的记录
3.inner join(等值连接、内连接) 只返回两个表中关联字段相等的记录
商品表:(goods_id是关联字段)
+----------+------------+-------------+-------------+----------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn |
+----------+------------+-------------+-------------+----------+
| 1 | 衬衫 | 100 | 10 | 201701 |
| 2 | 短裤 | 200 | 10 | 201702 |
| 3 | 秋裤 | 300 | 10 | 201703 |
| 4 | 毛衣 | 400 | 10 | 201704 |
+----------+------------+-------------+-------------+----------+
属性表:
+----+----------+-------+------+--------+
| id | goods_id | color | size | weight |
+----+----------+-------+------+--------+
| 1 | 1 | 黑色1 | 3 | 3 |
| 2 | 1 | 黑色2 | 3 | 3 |
| 3 | 2 | 黑色3 | 3 | 3 |
| 4 | 3 | 黑色4 | 3 | 3 |
| 5 | 5 | 黑色5 | 3 | 3 |
+----+----------+-------+------+--------+
1.左连接sql:select g.*,a.* from goods as g left join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
| 2 | 短裤 | 200 | 10 | 201702 | 3 | 2 | 黑色3 | 3 | 3 |
| 3 | 秋裤 | 300 | 10 | 201703 | 4 | 3 | 黑色4 | 3 | 3 |
| 4 | 毛衣 | 400 | 10 | 201704 | NULL | NULL | NULL | NULL | NULL |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
需要注意的是:
1)如果两张表都是查询所有(即 *),就会导致关联字段的重复,当后面的字段覆盖了前面的字段,就有可能出现NULL值;
2)没有匹配的值都是NULL
2.右连接sql:略
3.内连接sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
| 2 | 短裤 | 200 | 10 | 201702 | 3 | 2 | 黑色3 | 3 | 3 |
| 3 | 秋裤 | 300 | 10 | 201703 | 4 | 3 | 黑色4 | 3 | 3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
同样需要注意重复字段的问题
这里用到了on后接条件语句,顺便查了下on、where、having的区别
1.有where的sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id where g.goods_id = 1;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
注意where的位置一定要在on后面,否则会报错;ON根据限制条件对数据库记录进行过滤,然后生产临时表;而WHERE是在临时表生产之后,根据限制条件从临时表中筛选结果。
2.有关区别解释:
1)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。
2)on只有在多表联查时才会用到,在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤
3)HAVING不能单独出现,只能出现在GROUP BY子句中,HAVING是在聚集函数计算结果出来之后筛选结果,查询结果只返回符合条件的分组
例如sql:select goods_name from goods group by goods_name having sum(goods_price) < 400;
+------------+
| goods_name |
+------------+
| 短裤 |
| 秋裤 |
| 衬衫 |
+------------+
一定要出现分组和聚集函数
用到了distinct,简单记录下去重复:
select *,count(distinct goods_mount) from goods;
1.left join(左连接) 返回左表中的所有记录和右表中关联字段相等的记录
2.right join(右连接) 返回右表中的所有记录和左表中关联字段相等的记录
3.inner join(等值连接、内连接) 只返回两个表中关联字段相等的记录
商品表:(goods_id是关联字段)
+----------+------------+-------------+-------------+----------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn |
+----------+------------+-------------+-------------+----------+
| 1 | 衬衫 | 100 | 10 | 201701 |
| 2 | 短裤 | 200 | 10 | 201702 |
| 3 | 秋裤 | 300 | 10 | 201703 |
| 4 | 毛衣 | 400 | 10 | 201704 |
+----------+------------+-------------+-------------+----------+
属性表:
+----+----------+-------+------+--------+
| id | goods_id | color | size | weight |
+----+----------+-------+------+--------+
| 1 | 1 | 黑色1 | 3 | 3 |
| 2 | 1 | 黑色2 | 3 | 3 |
| 3 | 2 | 黑色3 | 3 | 3 |
| 4 | 3 | 黑色4 | 3 | 3 |
| 5 | 5 | 黑色5 | 3 | 3 |
+----+----------+-------+------+--------+
1.左连接sql:select g.*,a.* from goods as g left join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
| 2 | 短裤 | 200 | 10 | 201702 | 3 | 2 | 黑色3 | 3 | 3 |
| 3 | 秋裤 | 300 | 10 | 201703 | 4 | 3 | 黑色4 | 3 | 3 |
| 4 | 毛衣 | 400 | 10 | 201704 | NULL | NULL | NULL | NULL | NULL |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
需要注意的是:
1)如果两张表都是查询所有(即 *),就会导致关联字段的重复,当后面的字段覆盖了前面的字段,就有可能出现NULL值;
2)没有匹配的值都是NULL
2.右连接sql:略
3.内连接sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
| 2 | 短裤 | 200 | 10 | 201702 | 3 | 2 | 黑色3 | 3 | 3 |
| 3 | 秋裤 | 300 | 10 | 201703 | 4 | 3 | 黑色4 | 3 | 3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
同样需要注意重复字段的问题
这里用到了on后接条件语句,顺便查了下on、where、having的区别
1.有where的sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id where g.goods_id = 1;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| 1 | 衬衫 | 100 | 10 | 201701 | 1 | 1 | 黑色1 | 3 | 3 |
| 1 | 衬衫 | 100 | 10 | 201701 | 2 | 1 | 黑色2 | 3 | 3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
注意where的位置一定要在on后面,否则会报错;ON根据限制条件对数据库记录进行过滤,然后生产临时表;而WHERE是在临时表生产之后,根据限制条件从临时表中筛选结果。
2.有关区别解释:
1)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。
2)on只有在多表联查时才会用到,在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤
3)HAVING不能单独出现,只能出现在GROUP BY子句中,HAVING是在聚集函数计算结果出来之后筛选结果,查询结果只返回符合条件的分组
例如sql:select goods_name from goods group by goods_name having sum(goods_price) < 400;
+------------+
| goods_name |
+------------+
| 短裤 |
| 秋裤 |
| 衬衫 |
+------------+
一定要出现分组和聚集函数
用到了distinct,简单记录下去重复:
select *,count(distinct goods_mount) from goods;