SQL中三个UNION组合结果排序及替代查询方案咨询
搞定UNION查询的排序与优化方案
嘿,我来帮你梳理下这个SQL查询的问题和优化方向~
先提个当前SQL的小隐患
首先UNION有个硬性要求:前后两个查询的列数必须完全一致,而且对应列的数据类型得能兼容。你现在第一个查询返回5列:episode_id, ep_title, series_id, title, pic,那movies表得正好也是5列,且每列的顺序、类型都能对上,不然直接就报错啦,这一点得先确认哦。
给UNION结果排序的正确姿势
要给整个UNION后的结果排序,直接在最后加ORDER BY就行,但得注意用的列名要能匹配(或者用列的位置序号,不过更推荐用列名,清晰不容易错)。比如:
SELECT episode.episode_id, episode.ep_title, series.series_id, series.title, series.pic FROM episode RIGHT JOIN series ON episode.series_oid=series.series_id UNION SELECT * FROM movies ORDER BY title ASC; -- 这里假设movies表的第4列是title类型的字段
不过更稳妥的是给列统一起别名,避免两边列名不一致的问题:
SELECT episode.episode_id AS content_id, episode.ep_title AS sub_title, series.series_id AS parent_id, series.title AS main_title, series.pic AS cover FROM episode RIGHT JOIN series ON episode.series_oid=series.series_id UNION SELECT movie_id AS content_id, movie_subtitle AS sub_title, NULL AS parent_id, -- 如果movies没有对应的parent_id,用NULL填充就行 movie_title AS main_title, movie_pic AS cover FROM movies ORDER BY main_title ASC;
更高效的替代方案
1. 用UNION ALL代替UNION(如果不需要去重)
UNION会自动帮你去重,但这会额外消耗性能。如果剧集和电影的结果根本不可能重复(毕竟是不同类型的内容),直接换成UNION ALL,速度会快不少:
SELECT episode.episode_id AS content_id, episode.ep_title AS sub_title, series.series_id AS parent_id, series.title AS main_title, series.pic AS cover, 'episode' AS content_type -- 加个类型标识,方便后续区分是剧集还是电影 FROM episode RIGHT JOIN series ON episode.series_oid=series.series_id UNION ALL SELECT movie_id AS content_id, movie_subtitle AS sub_title, NULL AS parent_id, movie_title AS main_title, movie_pic AS cover, 'movie' AS content_type FROM movies ORDER BY main_title ASC;
2. 别用SELECT *,明确列映射
你现在写了SELECT * FROM movies,万一以后movies表加了列或者改了列顺序,整个查询直接就崩了。不如像上面那样,把每一列都明确写出来,和第一个查询的列一一对应,再用别名统一字段名,可读性和维护性都强很多。
3. 加个类型标识更实用
上面例子里加的content_type字段,能让你在结果里一眼区分出是剧集关联的内容还是电影,后续业务处理的时候会方便很多,比如前端展示不同的样式之类的。
额外小提醒
- 如果
RIGHT JOIN是为了保留所有series的数据(哪怕没有对应的episode),那这个写法没问题;如果只需要有episode的series,换成INNER JOIN会更高效。 - 要是想多条件排序,比如先按类型排,再按标题排,可以写成
ORDER BY content_type, main_title ASC。
内容的提问来源于stack exchange,提问作者AGOU CHAMSOU
相关产品推荐
相关产品推荐

