SQL常见问题整理(三)

6.连接与子查询

(1)表之间的结合
join
内连接:生成的结果只显示两个表都有的值
外连接:不仅可以生成两个表都有的值,还可以显示只有一个表中存在的值
(2)查找表之间不匹配的行
使用外连接(left join 或right join):当需要一个表中找到没有匹配(或另一个表中不存在 )的值时,应该想“这是一个left join的问题”
另一个找出一个表有另一个表中没有的值的方法是not in子查询:select * from artist where a_id not in (select a_id from painting)
(3)识别并删除不匹配或独立存在的行
使用带有not in子查询的delete:delete from sales_region where region_id not in (select region_id from sales_volume)
(4)表的自我比较
“自连接”,执行方式与其他连接非常相似,只是必须使用表的别名,再能在语句中以不同的方式引用同一个表:select p2.title from painting as p1 inner join painting as p2 on p1.a_id where p1.title=‘The Potato Eaters’
(5)生成主从复合结构列表和汇总
一对多,使用连接,但需要根据问题选择合适的连接类型,如果生成的列表只包含一些详情信息的主表行,那么可以使用基于主表主键的内连接,如果生成的列表包含所有主表行,甚至是那些没有详细信息的行,那么需要使用外连接
(6)列举多对多的关系
需要第三个表来关联两个主表,并提供一个三向连接来生成它们之间的对应关系
(7)查找每组的最小值或最大值
将最值出存在定义的变量中,然后通过该变量来找出包含该价格的行,并从中检索其他列:set @max_price=(select max(price) from painting);select artist.name,painting.title,painting.price from artist inner join painting on painting.a_id=artist.a_id where painting.price=@max_price
创建一个临时表来保存每组的最大值或最小值,然后将临时表与原表连接起来,并输出每个组中匹配的行:create table tmp select max(price) as max_price from painting;select artist.name,painting.title,painting.price from artist inner join painting inner join tmp on painting.a_id=artist.a_id and painting.price=tmp.max_price
如果通过一条查询语句解决问题,可以在from子句中使用子查询:select artist.name,painting.title,painting.price from artist inner join painting inner join (select a_id,max(price) as max_price from painting group by a_id) as tmp on painting.a_id=tmp.a_id and painting.price=tmp.max_price
利用left join进行表的自我连接:select p1.a_id,p1.title,p1.price from painting as p1 left join painting as p2 on p1.a_id=p2.a_id and p1.price<p2.price where p2.a_id is null
(8)利用连接填充或找出列表中的缺口
创建一个参考表保存每个类别,并通过left join连接该参考表和数据表,然后创建汇总信息
创建参考表:create table dates(d DATE);insert into dates(d) values(‘2014-07-26’),(‘2014-07-27’)
使用left join将参考表与driver_log表连接起来:select dates.d,count(driver_log.trav_dates) as drivers from dates left join driver_log on dates.d=driver_log.trav_date group by d order by d
(9)利用join控制查询的排序
导出排序的信息,并将其存储在辅助表中,然后连接原表与辅助表,并利用辅助表来控制排序:create table tmp select name,sum(miles) as driver_miles from driver_log group by name;select * from tmp order by driver_miles DESC;
或者使用临时表:select tmp.driver_miles, driver_log.* from driver_log inner join (select name,sum(miles) as driver_miles from driver_log group by name) as tmp on driver_log.name = tmp.name order by tmp.driver_miles DESC, driver_log.trav_date;

总结:灵活使用表连接,group by、临时表或子查询

猜你喜欢

转载自blog.csdn.net/weixin_47970003/article/details/123724275
今日推荐