如何强制子查询返回单行?MySQL #1241报错修复咨询
修复SQL错误#1241并实现15个分组查询需求
首先,咱们先搞清楚你为啥会碰到#1241 - Operand should contain 1 column(s)这个错误:
你在主查询的SELECT列表里嵌套的那个子查询,一下子返回了7列数据(date_time、score、type、post_id、table_code、comment_id、context),但SQL规则里,作为SELECT列表中的一个“字段”,子查询必须只能返回1列1行,多列的话数据库就不知道该怎么把它当成一个字段处理了,自然就报错。
接下来针对你的需求——选择15个分组,给你两种常见场景的修复方案:
场景1:获取15个分组对应的所有原始事件记录
如果你想拿到这15个分组下的每一条原始events数据,同时带上分组后的聚合结果(比如分组内的最小时间、总分),可以把分组子查询作为派生表和主表关联,写法如下:
SELECT e.id, e.table_code, g.group_min_date, g.group_total_score, g.type, g.post_id, g.table_code AS group_table_code, g.comment_id, g.context FROM events e -- 关联我们筛选出的15个分组 JOIN ( SELECT MIN(date_time) AS group_min_date, SUM(score) AS group_total_score, type, post_id, table_code, comment_id, context FROM events WHERE author_id = 32 GROUP BY type, post_id, table_code, comment_id, context ORDER BY MIN(date_time) DESC LIMIT 15 -- 取最新的15个分组 ) g ON e.type = g.type AND e.post_id = g.post_id AND e.table_code = g.table_code AND e.comment_id = g.comment_id AND e.context = g.context WHERE e.author_id = 32 ORDER BY e.seen ASC, e.date_time DESC;
场景2:筛选出日期不早于15个分组中最早日期的记录
如果你只是想保留author_id=32且date_time不早于这15个分组里最小日期的记录,可以先通过嵌套子查询拿到这个最小日期,再用它做筛选:
SELECT e.id, e.table_code FROM events e WHERE e.author_id = 32 AND e.date_time >= ( -- 先拿到15个分组里的最小日期 SELECT MIN(group_min_date) FROM ( SELECT MIN(date_time) AS group_min_date FROM events WHERE author_id = 32 GROUP BY type, post_id, table_code, comment_id, context ORDER BY MIN(date_time) DESC LIMIT 15 ) AS sub_groups ) ORDER BY e.seen ASC, e.date_time DESC;
关于“强制子查询仅返回单行”
如果你的业务场景确实需要子查询只返回1行数据,只需要在子查询末尾加上LIMIT 1,同时确保你的分组/筛选条件足够精准,比如要拿到最新的单个分组:
SELECT e.id, e.table_code FROM events e JOIN ( SELECT MIN(date_time) AS group_min_date, type, post_id, table_code, comment_id, context FROM events WHERE author_id = 32 GROUP BY type, post_id, table_code, comment_id, context ORDER BY MIN(date_time) DESC LIMIT 1 -- 强制返回单行 ) g ON e.type = g.type AND e.post_id = g.post_id AND e.table_code = g.table_code AND e.comment_id = g.comment_id AND e.context = g.context WHERE e.author_id = 32 ORDER BY e.seen ASC, e.date_time DESC;
另外还要提一句,你原来SQL里e.date_time >= MIN(g.date_time)的写法是无效的:一方面WHERE子句执行时,SELECT里的别名还没被解析;另一方面聚合函数MIN()不能直接用在WHERE里,必须通过子查询提前计算出值再用。
内容的提问来源于stack exchange,提问作者Martin AJ
相关产品推荐
相关产品推荐

