学习mysql中的子查询 相关子查询
一下是自己浏览到的文章:
MySQL子查询
这篇文章,让自己明白了EXISTS: Mysql使用exists的子查询
今天自己回顾查询我的评论列表的代码时候,发现自己当初写的很蠢。因为自己不会把子查询,和 join 搞懵了,不知道怎么查。今天特意写下这篇文章总结。
技术经理说过。join 连接就是扩展列。子查询就是增加where 条件。
如果自己想增加列, 首先想到的是就用join(也可以在select 后面写一个子查询), 如果自己想增加判断条件,就可以考虑子查询。
关联表
查询我的评论,要求的数据结构。
评论内容
被评论帖子作者头像 , 被评论帖子作者姓名, 被评论帖子标题
解题思路就应该是评论表, 左关联帖子表, 左关联用户表, 摘出评论内容字段,作者头像字段,标题字段。
SELECT
t2.`subject`, t3.avatar, t1.*
FROM
pico_forum_post t1
LEFT JOIN pico_forum_thread t2 ON t1.tid = t2.tid
LEFT JOIN pico_common_member t3 ON t1.authorid = t3.uid
WHERE
t1.authorid = #{uid,jdbcType=INTEGER}
AND t1.position > 1
子查询-MySQL相关子查询
一般在子查询中,程序先运行在嵌套在最内层的语句,再运行外层。因此在写子查询语句时,可以先测试下内层的子查询语句是否输出了想要的内容,再一层层往外测试,增加子查询正确率。否则多层的嵌套使语句可读性很低。
从子查询是否独立运行可以区别为:独立子查询,和相关子查询。
相关子查询:它依赖于外部查询出来的结果集中每一条记录,作为输入条件。
相关的子查询取决于外部查询。
对外部查询中的每一行对相关子查询进行一次评估。
通常在相关子查询中使用EXISTS和NOT EXISTS。
-- 查询一个一个学生成绩高于自己平均成绩的那么课程,和学生信息
SELECT
t1.*
FROM
Score t1
WHERE
t1.s_score > ( SELECT AVG(t2.s_score) FROM Score t2 WHERE t2.s_id = t1.s_id )
-- 在以下查询中,我们查询选择购买价格高于每个产品线中的产品的平均购买价格的产品
SELECT
productname,
buyprice
FROM
products p1
WHERE
buyprice > (SELECT
AVG(buyprice)
FROM
products
WHERE
productline = p1.productline)
相关子查询 写在select 后面
<select id="selectPostListByBlockId" parameterType="java.util.Map" resultType="com.basetnt.bss.dto.ForumThreadDTO">
SELECT t1.*, t3.name, t3.moderators, t4.message, t5.avatar, (SELECT t6.id FROM pico_forum_likes_collection t6 WHERE t1.tid = t6.postid AND t6.userid = #{uid, jdbcType=INTEGER} AND t6.type = 100 ) AS memberLikedId
FROM
pico_forum_thread t1
LEFT JOIN pico_forum_threadclass t3 ON t1.typeid = t3.typeid
LEFT JOIN ( SELECT tid, LEFT(message, 200) AS message FROM pico_forum_post WHERE position = 1 AND isdeleted = 0 ) t4 ON t1.tid = t4.tid
LEFT JOIN pico_common_member t5 ON t1.authorid = t5.uid
<where>
t1.`fid` = #{fid, jdbcType=INTEGER} AND t1.`displayorder` IN ( '0', '1', '2', '3', '4' )
<if test="essence != null">
AND t1.digest > 0
</if>
</where>
<if test="default != null">
ORDER BY t1.displayorder DESC, t1.dateline DESC
</if>
<if test="post != null">
ORDER BY t1.dateline DESC, t1.displayorder DESC
</if>
<if test="reply != null">
ORDER BY t1.lastpost DESC, t1.displayorder DESC
</if>
</select>
Mysql使用exists的子查询 特别注意
也就是下面这段话,使得自己明白了EXISTS 的用法。
1. 首先自己要明白: 使用了EXISTS 的子查询是相关子查询。
2. 既然是相关子查询,那么他也是将外查询的结果集的每一行记录,
3. 传入到子查询中作为条件判断。
4. 当条件成立,使用EXISTS 则返回true, 否则返回false。
5. 如果返回true, 则外查询的字段,则被查询出来。
6. 特别注意:
(1)该子查询,如果其仅仅是为了得到“有没有数据”的结果,则通常此时对主查询就失去应用意义;
(2)实际上,该子查询,通常都需要在子查询(内部)中来使用主查询(外部)的某些字段作为条件数据,这样才能具有一定的实用意义。
其实,这种情况下的子查询,对于mysql内部,是做了“内连接之后”的结果。
举例1:
select * from product where exists(
select * from product_type
where product_type.protype_id = product.protype_id
and protype_name like '%码%'
);