MySQL - join/group 连接返回太多项目

MySQL - join/group concat returning too many items

我有一个简单的查询,可以查询正面交锋中的胜负情况 table。

SELECT
    SUM(CASE WHEN score_w > score_m THEN 1 ELSE 0 END) AS wins_w,
    SUM(CASE WHEN score_m > score_w THEN 1 ELSE 0 END) AS wins_m,
    SUM(CASE WHEN score_w = score_m THEN 1 ELSE 0 END) AS draws
FROM 6dos7me3xn8

一切顺利。我得到一行,我需要的数据作为列。

现在我还想提取一组最近 三个 匹配日期的列表。我试过了:

SELECT
    SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
    SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
    SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
    GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3) jn

...但是 LIMIT 似乎没有效果 - 我得到 all 的日期组 concat',而不仅仅是 3.

我还尝试删除 JOIN 并将 GROUP_CONCAT 替换为

GROUP_CONCAT((SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3)) AS recent

...但是 'Subquery returns more than 1 row.'

的错误

我确定这很简单,但我做错了什么?

您正在做 cross join。要获取最近的三个日期,您可以使用:

FROM (SELECT mn.*, DENSE_RANK() OVER (ORDER BY date desc) as seqnum
      FROM 6dos7me3xn8 mn
     ) mn
WHERE seqnum <= 3

如果你是 运行 MySQL 8.0,你可以用 window 函数来做到这一点:

select
    sum(score_w > score_m) as wins_w,
    sum(score_m > score_w) as wins_m,
    sum(score_w = score_m) as draws,
    group_concat(case when rn <= 3 then date end) as recent
from (
    select t.*, row_number() over(order by date desc) rn
    from `6dos7me3xn8` t
) t

子查询按日期降序排列记录;然后我们可以在外部查询中使用该信息。请注意,您不需要 case 表达式:MySQL 将 true/false 条件计算为数字内容中的 1/0。

在早期版本中,更简单的方法可能是行限制子查询:

select
    sum(score_w > score_m) as wins_w,
    sum(score_m > score_w) as wins_m,
    sum(score_w = score_m) as draws,
    (select group_concat(date) from (select date from `6dos7me3xn8` order by date desc limit 3) t) as recent
from `6dos7me3xn8`

您没有 ON 子句来指定子查询与您要加入的 table 之间的关系。所以你得到一个完整的叉积。

您还需要 ORDER BY 使其成为 return 3 个最近的日期,而不是任何 3 个日期。

SELECT
    SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
    SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
    SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
    GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (
    SELECT DISTINCT date 
    FROM 6dos7me3xn8 
    ORDER BY date DESC
    LIMIT 3
) jn ON jn.date = mn.date