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
我有一个简单的查询,可以查询正面交锋中的胜负情况 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