MySQL创建月度未租借视频视图报1111错误的解决求助
错误原因及解决方案
1 报错直接原因
你出现1111错误的核心原因是:SQL执行顺序中,WHERE 子句的执行优先级早于 GROUP BY 分组和聚合函数计算,你在WHERE里直接用聚合结果别名amount做筛选,系统此时还没计算出amount的值,且聚合函数不能直接放在WHERE子句中使用。
要筛选分组后的聚合结果,必须使用HAVING子句,同时GROUP BY需要包含SELECT中所有非聚合字段,否则开启ONLY_FULL_GROUP_BY模式的MySQL环境还会抛出额外错误。
仅解决报错的修正写法如下(注意这个写法逻辑上无法实现你要的「未被租借视频统计」需求):
CREATE VIEW `Video not rented` AS SELECT loan.period, loan.v_id, COUNT(*) AS amount FROM loan GROUP BY loan.period, loan.v_id HAVING amount = 0;
2 正确实现逻辑说明
你当前的写法逻辑存在本质问题:loan 表存储的是所有已经产生的租借记录,只要出现在loan表里的视频v_id至少有1条租借记录,COUNT(*)的结果不可能为0,所以你永远筛选不到符合条件的记录。
要统计未被租借的视频,需要基于全量视频的集合做左连接匹配当月的租借记录,匹配不到的就是未被租借的视频,分两种场景实现:
场景1:存在单独的视频主表
假设视频主表名为video,主键为v_id,可以直接用主表的全量视频做匹配,写法如下:
CREATE VIEW `Video not rented` AS SELECT -- 生成和loan表格式一致的当月周期值,如需统计其他月份可替换为指定值 DATE_FORMAT(CURDATE(), '%Y-%m') AS period, v.v_id, 0 AS amount FROM video v LEFT JOIN loan l ON v.v_id = l.v_id AND l.period = DATE_FORMAT(CURDATE(), '%Y-%m') -- 匹配不到租借记录的就是当月未出租的视频 WHERE l.v_id IS NULL;
场景2:无单独的视频主表
如果没有单独的视频主表,只能基于loan表历史出现过的所有v_id做统计,写法如下:
CREATE VIEW `Video not rented` AS SELECT DATE_FORMAT(CURDATE(), '%Y-%m') AS period, all_v.v_id, 0 AS amount -- 先取历史所有出现过的视频id FROM (SELECT DISTINCT v_id FROM loan) all_v LEFT JOIN loan l ON all_v.v_id = l.v_id AND l.period = DATE_FORMAT(CURDATE(), '%Y-%m') WHERE l.v_id IS NULL;
内容的提问来源于stack exchange,提问作者Juan Pablo Clavijo
相关产品推荐
相关产品推荐

