mysqljoin⼦查询_MySQL⼦查询join连接union
where型⼦查询
指把内层查询的结果作为外层查询的⽐较条件,典型题:查询id最⼤,最贵商品
如果where 列 =(内层sql),则内层sql返回的必须是单⾏单列,单个值;
如果where 列 in(内层sql),则内层sql只返回单列,可以多⾏。
--查出本⽹站最新的(goods_id最⼤)的⼀条商品--按goods_id desc排序,再取第⼀⾏
select goods_id,goods_name fromgoodsorder by goods_id desc limit 0,1;--查出本⽹站最新的(goods_id最⼤)⼀条商品,要求:不⽤排序--其实很简单,实质就是下⾯的语句(得到最⼤的goods_id)--select goods_id,goods_name from goods where goods_id = 32;--查出最⼤的goods_id -> select max(goods_id) from goods;
select goods_id,goods_name fromgoodswheregoods_id= (select max(goods_id) from goods);
⽤where型⼦查询,查询"每个栏⽬下goods_id最⼤的商品"?
-
-先查出所有栏⽬下最⼤的商品id,然后根据上步的id在商品表中取出相应id的商品
select goods_id,goods_name,cat_id fromgoodswhere goods_id in(select max(goods_id) from goods group by cat_id)
from型⼦查询
把内层的查询结果当成临时表,供外层sql再次查询,典型题:查询id最⼤,最贵商品
--查出本⽹站最新的(goods_id最⼤)的⼀条商品
select goods_id,cat_id,goods_name fromgoodsorder by goods_id DESC,cat_id ASC;--如果存在上述查询结果的这张表,表名为tmp,则只需select * from tmp group by cat_id;就可以得到结果--因为group by取每个分组下第⼀次出现的⾏
inputbox必须设置的参数select * from (selectgoods_id,cat_id,goods_namefromgoodsorder by goods_id DESC,cat_id ASC) astmpgroup by cat_id
order by goods_id;
exists型⼦查询
sql的九个常用语句大全把外层sql的结果,拿到内层sql去测试,如果内层sql成⽴,则该⾏取出
--要求:查出有商品的栏⽬->取栏⽬表,且只取有商品的栏⽬--假设栏⽬cat_id为N,则select * from goods where cat_Id = N -->能取出数据,则说明该栏⽬有商品
select cat_id,cat_name fromcategorywhere exists(select * from goods where goods.cat_id=category.cat_id);
连接join
集合知识
集合的特点:⽆序性、唯⼀性
集合的运算:求交集,并集,笛卡尔积(相乘)
笛卡尔积:即集合的元素,做两两的组合
例:集合a:2,3,5 集合b:4,7集合a*b?
得到⼀个新集合(2,4)(2,7)(3,4)(3,7)(5,4)(5,7)
表与集合的关系
⼀个集合就是⼀张表,表中的⼀条记录就是集合中的⼀个元素
两张表做笛卡尔积SELECT * FROMT1,T2;
从⾏的⾓度看:就是2表每⼀⾏,两两组合。
从列的⾓度看:结果集中的列,是两表的 列名的相加(列可以重复)
如果在多表联查时,某⼀列名,在2张或2张以上表都有,则需要在列名前,指定表名,即表名.列名--利⽤2表全相乘来查询,⽣成⼤量数据,占⽤⼤量内存,效率低下
SELECTgoods_id,goods_name,cat_nameFROMgoods,categoryWHERE goods.cat_id = category.cat_id;
1.左连接
假设A表在左,不动,B表在A表的右边滑动,A表与B表通过⼀个关系来筛选B表的⾏。
陕西二郎山风景区A LEFT JOIN
B ON条件 #当条件为真,则B表对应的⾏取出
ALEFT JOIN B ON --这⼀块形成的也是⼀个结果集,可以看成⼀张表,设为C--C表的可以查询的列是A,B的列--即如此,可以对C表做查询,⾃然where,group by,having,order by,limit--改进上⾯的笛卡尔积查询,利⽤左连接
SELECTgoods_id,goods.cat_id,goods_name,cat_nameFROMgoodsLEFT JOIN category ON goods.cat_id = category.cat_id;
2.右连接
--左右连接是可以互换的
A LEFT JOIN
B ==> B RIGHT JOINA--上⾯的查询⽤右连接
SELECTgoods_id,goods.cat_id,goods_name,cat_nameFROMcategoryRIGHT JOIN goods ON goods.cat_id =category.cat_id;--既然左右连接可以互换,尽量⽤左连接,出于移植时兼容性⽅⾯的考虑。
3.内连接
如果从集合的⾓度看,A inner join B 和 B inner join A,取交集,内连接是左右连接的交集。
外连接:结果是左右连接的并集,但mysql中不⽀持外连接。
⾯试题
--赛程表
+-----+-----+-----+------+------------+
| mid | hid | gid | mres | mtime |
+-----+-----+-----+------+------------+
| 1 | 1 | 2 | 2:0 | 2006-05-21 |
| 2 | 2 | 3 | 1:2 | 2006-06-21 |
| 3 | 3 | 1 | 2:5 | 2006-06-25 |
| 4 | 2 | 1 | 3:2 | 2006-07-25 |
+-----+-----+-----+------+------------+--参赛队伍表
thinkphp6 primer 前后端分离实战入门+-----+----------+
| tid | tname |
+-----+----------+
| 1 | 国安 |
| 2 | 申花 |
mysql面试题sql| 3 | 公益联队 |
+-----+----------+--Match的hID与gID都与Team中的tID关联--查出 2006-6-1 到2006-7-1之间举⾏的所有⽐赛,并且⽤以下形式列
出:--拜仁 2:0 不来梅 2006-6-21
ame as ame as ime frommleft join t as t1 on m.hid =t1.tidleft join t as t2 on m.gid =t2.tidwhere mtime between '2006-06-01' and '2006-07-01';
union 联合
合并2条或多条语句的结果,union合并的是结果集,不区分来⾃于哪张表。
--语法:
sql1 unionsql2--要求查出价格低于30元和价格⾼于4000元的商品,不能⽤or
SELECT goods_id,goods_name,shop_price FROM goods WHERE shop_price <30
UNION
SELECT goods_id,goods_name,shop_price FROM goods WHERE shop_price >4000;--合并2张不同表的数据
SELECT user_name,msg_content,msg_time FROM feedback WHERE msg_status = 1
UNION
SELECT user_name,content as msg_content,add_time as msg_time FROM comment WHERE STATUS = 1;
如果取出的结果集,列名称不⼀样,同样可以union,并且取出的最终列名以第1条sql为准。
--改结果集的列名以第⼀条sql为准,即user_name,msg_content,msg_time
后端项目模板下载网站SELECT user_name,msg_content,msg_time FROM feedback WHERE msg_status = 1
UNION
SELECT user_name,content ,add_time FROM comment WHERE STATUS = 1;
只要结果集中的列数⼀致就可以⽤union进⾏联合操作。即使列的类型不⼀致也可以,但这样没什么意义。
union后的数据可以进⾏排序(order by)操作 sql1 union sql2 order by 字段。内层的order by语句单独使⽤,不会影响结果集,仅排序,在执⾏期间,就被mysql的代码分析器给优化掉了;内层的order by必须能够影响结果集时才有意义,⽐如配合limit使⽤。
-
-⽤union取出第4个栏⽬的栏⽬,和第5个栏⽬的商品,并按价格升序排列--内层的ORDER BY shop_price DESC不会起作⽤,⽆意义,被查询优化器优化掉了
SELECT goods_id,cat_id,goods_name,shop_price from goods where cat_id=4 ORDER BY shop_price DESC
UNION
SELECT goods_id,cat_id,goods_name,shop_price from goods where cat_id =5 ORDER BY shop_price DESC
ORDER BY shop_price ASC;--第3个栏⽬下,价格前3⾼的商品,和第4个栏⽬下,价格前2⾼的商品,⽤union来完成--因为有
limit,order by将影响返回值,有意义,不会被查询优化器优化掉。
(SELECT goods_id,cat_id,goods_name,shop_price fromgoodswhere cat_id = 3 order by shop_price DESC limit
3)UNION(SELECT goods_id,cat_id,goods_name,shop_price fromgoodswhere cat_id = 4 order by shop_price DESC limit 2)
如果union后的结果有重复(即某2⾏或N⾏,所有的列值都相同)默认会去重,如果不想去重,须⽤union all。
--⾯试题
A表+----+-----+
| id | num |
+----+-----+
| a | 5 |
| b | 10 |
| c | 15 |
| d | 10 |
+----+-----+
B表+----+-----+
| id | num |
+----+-----+
| b | 5 |
| c | 10 |
| d | 20 |
| e | 99 |
+----+-----+
须得到如下结果+------+----------+
| id | sum(num) |
+------+----------+
| a | 5 |
| b | 15 |
| c | 25 |
| d | 30 |
| e | 99 |
+------+----------+--可⽤左连接来做
select a.*,b.* from a left join b on a.id =b.id;--再把上⾯看成⼀张临时表,再次from型⼦查询,计算a.num+b.num的和,ifnull函数--⽽且少了e,只好左联union右联,再⼦查询。很复杂--另⼀思路,先把2表数据union到⼀块,再sum函数来相加
SELECT * FROMaUNION
SELECT * FROMb--再sum⼀下
select id,sum(num) from(SELECT * FROMaUNION
SELECT * FROMb
)as tmp group byid;--不需要去重复 只需将union改成union all
select id,sum(num) from(SELECT * FROMaUNION ALL
SELECT * FROMb
)as tmp group by id;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论