我有以下MySQL查询:
(SELECT c.Channel as name, count(*) as total_episode
FROM (
SELECT a.aid, a.vid
FROM videoItem v INNER JOIN aid2vid a USING(vid)
GROUP BY a.aid
) a1 INNER JOIN channelListingItem c USING(aid)
GROUP BY c.Channel
)
UNION
(SELECT c1.Channel as name, 0 as total_episode
FROM channelListingItem c1 LEFT JOIN (
SELECT c.Channel FROM (
SELECT a.aid, a.vid
FROM videoItem v INNER JOIN aid2vid a USING(vid)
GROUP BY a.aid
) a1 INNER JOIN channelListingItem c USING(aid)
GROUP BY c.Channel
) c2 USING(Channel)
WHERE c2.Channel is null
GROUP BY name
);
基本上,这句话的作用是在每个频道中获得正确的计数剧集。为后续表(videoItem)中的vid o vid分配零。
请注意
SELECT a.aid, a.vid
FROM videoItem v
INNER JOIN aid2vid a USING(vid)
GROUP BY a.aid
重复两次,并解释这个MySQL语句我没有看到MySQL重用查询结果。
+----+--------------+------------+------+----------+---------+---------+----------+------+---------------------------------+
| id | select_type | table | type | pos_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+------+----------+---------+---------+----------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 313 | Using temporary; Using filesort |
| 1 | PRIMARY | c | ALL | idx_vid | NULL | NULL | NULL | 616 | Using where; Using join buffer |
| 2 | DERIVED | a | ALL | vid | NULL | NULL | NULL | 1015 | Using temporary; Using filesort |
| 2 | DERIVED | v | ref | idx_vid | idx_vid | 32 | db.a.vid | 10 | Using index |
| 3 | UNION | c1 | ALL | NULL | NULL | NULL | NULL | 616 | Using temporary; Using filesort |
| 3 | UNION | <derived4> | ALL | NULL | NULL | NULL | NULL | 28 | Using where; Not exists |
| 4 | DERIVED | <derived5> | ALL | NULL | NULL | NULL | NULL | 313 | Using temporary; Using filesort |
| 4 | DERIVED | c | ALL | idx_vid | NULL | NULL | NULL | 616 | Using where; Using join buffer |
| 5 | DERIVED | a | ALL | vid | NULL | NULL | NULL | 1015 | Using temporary; Using filesort |
| 5 | DERIVED | v | ref | idx_vid | idx_vid | 32 | db.a.vid | 10 | Using index |
|NULL| UNION RESULT | <union1,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+------+----------+---------+---------+----------+------+---------------------------------+
11 rows in set (0.02 sec)
如何重构此MySQL语句? MySQL语句也有很好的重构工具吗?
感谢。
答案 0 :(得分:1)
我可能会这样,但我相信跟随提供与原始查询相同的结果。
它的要点是
total_episode
字段添加到LEFT JOIN
。COALESCE
返回total_episode
值或0
。SQL声明
SELECT c1.Channel as name
, COALESCE(total_episode, 0)
FROM channelListingItem c1
LEFT JOIN (
SELECT c.Channel
, count(*) as total_episode
FROM (
SELECT a.aid
, a.vid
FROM videoItem v
INNER JOIN aid2vid a ON a.vid = v.vid
GROUP BY
a.aid
) a1
INNER JOIN channelListingItem c ON c.aid = a1.aid
GROUP BY
c.Channel
) c2 ON c2.Channel = c1.Channel
GROUP BY
name
答案 1 :(得分:1)
这个似乎对我有用:
select Channel as name,count(distinct a1.aid) as total_episode
from channelListingItem c
left join
(
select a.aid, a.vid
from videoItem v INNER JOIN aid2vid a USING(vid)
) a1 on a1.aid = c.aid
group by Channel;
从我可以看到以下在内联视图中使用两次的查询:
SELECT a.aid, a.vid
FROM videoItem v INNER JOIN aid2vid a USING(vid)
GROUP BY a.aid
用于获取aid
和vid
中存在的videoItem
和aid2vid
值的明确列表。我已使用GROUP BY
替换了内联视图中的COUNT(DISTINCT)
以实现相同的功能,因为您未在查询的内联视图部分中使用任何聚合函数。
我认为您不需要将查询拆分为由联合加入的两个部分,即第1部分以获取剧集计数&gt; 0和第2部分得到剧集计数= 0.这可以在一个GROUP BY
中实现。
希望这有帮助!