如何按DATE_FORMAT(date,'%Y-%m-%d')限制20求和,如果大于20则求和剩余值?
How to sum value by DATE_FORMAT(date,'%Y-%m-%d') limit 20, and sum remaining value if greater than 20?
如何通过DATE_FORMAT(date,'%Y-%m-%d')
和id前20行数据求和,如果大于20则求和剩下的值,否则为0?假设我的数据低于 SQL,怎么办?非常感谢您的任何建议。
SELECT SUM(value), id, DATE_FORMAT(date,'%Y-%m-%d')
FROM test_table
GROUP BY id, DATE_FORMAT(date,'%Y-%m-%d')
sum(value) id DATE_FORMAT(date,'%Y-%m-%d')
--------------------------------------------
64.98 123456 2021-01-01
64.98 123456 2021-01-02
64.98 123456 2021-01-03
64.98 123456 2021-01-04
64.98 123456 2021-01-05
64.98 123456 2021-01-06
72.34 123456 2021-01-07
64.98 123456 2021-01-08
64.98 123456 2021-01-09
103.80 123456 2021-01-10
64.98 123456 2021-01-11
64.98 123456 2021-01-12
64.98 123456 2021-01-13
64.98 123456 2021-01-14
64.98 123456 2021-01-15
64.98 123456 2021-01-16
64.98 123456 2021-01-17
64.98 123456 2021-01-18
64.98 123456 2021-01-19
64.98 123456 2021-01-20
64.98 123456 2021-01-21
64.98 123456 2021-01-22
64.98 123456 2021-01-23
64.98 123456 2021-01-24
144.98 123456 2021-01-25
64.98 123456 2021-01-26
64.98 123456 2021-01-27
64.98 123456 2021-01-28
64.98 123456 2021-01-29
64.98 123456 2021-01-30
64.98 123456 2021-01-31
64.98 123456 2021-02-01
64.98 123456 2021-02-02
64.98 123456 2021-02-03
64.98 123456 2021-02-04
720.92 123456 2021-02-05
66.98 123456 2021-02-06
66.98 123456 2021-02-07
66.98 123456 2021-02-08
64.98 123456 2021-02-09
64.98 123456 2021-02-10
64.98 123456 2021-02-11
64.98 123456 2021-02-12
64.98 123456 2021-02-13
64.98 123456 2021-02-14
64.98 123456 2021-02-15
64.98 123456 2021-02-16
64.98 123456 2021-02-17
64.98 123456 2021-02-18
64.98 123456 2021-02-19
64.98 123456 2021-02-20
64.98 223456 2021-01-20
54.98 223456 2021-01-21
.................................
如果您使用的 MySQL 版本支持 window 功能,那么可能:
SELECT id,
SUM(CASE WHEN rn <= 20 THEN vals ELSE 0 END) AS 'SumOf1st20',
SUM(CASE WHEN rn > 20 THEN vals ELSE 0 END) AS 'SumOFOthers'
FROM
(SELECT SUM(value) AS vals, id, DATE_FORMAT(date,'%Y-%m-%d') AS dt,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY dt DESC) AS rn
FROM test_table
GROUP BY id, dt) v
GROUP BY id;
但我想知道这是否正是您想要的,因为您的示例数据似乎是您原始查询的结果。
这是一种在旧 MySQL 版本中复制 ROW_NUMBER()
功能的方法:
SELECT t1.*,
CASE WHEN id=@idx THEN @rnk := @rnk+1
ELSE @rnk := 1 END AS rn,
@idx := id
FROM (SELECT id,
SUM(value) AS vals, DATE_FORMAT(date,"%Y-%m-%d") AS dt
FROM test_table
GROUP BY id, dt)t1
CROSS JOIN (SELECT @rnk := 0, @idx := NULL) r
ORDER BY id, dt DESC
虽然,(在极少数情况下)我有这样的经历,但它没有像我预期的那样执行:行编号有时会弄乱。
经过进一步测试,这种“罕见情况”似乎正在这里发生。由于您的原始查询包含聚合,我将其与 v8 兼容 ROW_NUMBER()
进行比较,得到不同的结果。经观察,行号是在 ORDER BY xxx DESC
发生之前分配的。因此,从视觉上看,它确实按 date
相应地降序排序,但 rn
列 “不正确” 生成。我发现的解决方法是先在子查询中执行聚合,然后只尝试生成自定义行编号。请参阅我更新的查询和上面的 fiddle。
如何通过DATE_FORMAT(date,'%Y-%m-%d')
和id前20行数据求和,如果大于20则求和剩下的值,否则为0?假设我的数据低于 SQL,怎么办?非常感谢您的任何建议。
SELECT SUM(value), id, DATE_FORMAT(date,'%Y-%m-%d')
FROM test_table
GROUP BY id, DATE_FORMAT(date,'%Y-%m-%d')
sum(value) id DATE_FORMAT(date,'%Y-%m-%d')
--------------------------------------------
64.98 123456 2021-01-01
64.98 123456 2021-01-02
64.98 123456 2021-01-03
64.98 123456 2021-01-04
64.98 123456 2021-01-05
64.98 123456 2021-01-06
72.34 123456 2021-01-07
64.98 123456 2021-01-08
64.98 123456 2021-01-09
103.80 123456 2021-01-10
64.98 123456 2021-01-11
64.98 123456 2021-01-12
64.98 123456 2021-01-13
64.98 123456 2021-01-14
64.98 123456 2021-01-15
64.98 123456 2021-01-16
64.98 123456 2021-01-17
64.98 123456 2021-01-18
64.98 123456 2021-01-19
64.98 123456 2021-01-20
64.98 123456 2021-01-21
64.98 123456 2021-01-22
64.98 123456 2021-01-23
64.98 123456 2021-01-24
144.98 123456 2021-01-25
64.98 123456 2021-01-26
64.98 123456 2021-01-27
64.98 123456 2021-01-28
64.98 123456 2021-01-29
64.98 123456 2021-01-30
64.98 123456 2021-01-31
64.98 123456 2021-02-01
64.98 123456 2021-02-02
64.98 123456 2021-02-03
64.98 123456 2021-02-04
720.92 123456 2021-02-05
66.98 123456 2021-02-06
66.98 123456 2021-02-07
66.98 123456 2021-02-08
64.98 123456 2021-02-09
64.98 123456 2021-02-10
64.98 123456 2021-02-11
64.98 123456 2021-02-12
64.98 123456 2021-02-13
64.98 123456 2021-02-14
64.98 123456 2021-02-15
64.98 123456 2021-02-16
64.98 123456 2021-02-17
64.98 123456 2021-02-18
64.98 123456 2021-02-19
64.98 123456 2021-02-20
64.98 223456 2021-01-20
54.98 223456 2021-01-21
.................................
如果您使用的 MySQL 版本支持 window 功能,那么可能:
SELECT id,
SUM(CASE WHEN rn <= 20 THEN vals ELSE 0 END) AS 'SumOf1st20',
SUM(CASE WHEN rn > 20 THEN vals ELSE 0 END) AS 'SumOFOthers'
FROM
(SELECT SUM(value) AS vals, id, DATE_FORMAT(date,'%Y-%m-%d') AS dt,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY dt DESC) AS rn
FROM test_table
GROUP BY id, dt) v
GROUP BY id;
但我想知道这是否正是您想要的,因为您的示例数据似乎是您原始查询的结果。
这是一种在旧 MySQL 版本中复制 ROW_NUMBER()
功能的方法:
SELECT t1.*,
CASE WHEN id=@idx THEN @rnk := @rnk+1
ELSE @rnk := 1 END AS rn,
@idx := id
FROM (SELECT id,
SUM(value) AS vals, DATE_FORMAT(date,"%Y-%m-%d") AS dt
FROM test_table
GROUP BY id, dt)t1
CROSS JOIN (SELECT @rnk := 0, @idx := NULL) r
ORDER BY id, dt DESC
虽然,(在极少数情况下)我有这样的经历,但它没有像我预期的那样执行:行编号有时会弄乱。
经过进一步测试,这种“罕见情况”似乎正在这里发生。由于您的原始查询包含聚合,我将其与 v8 兼容 ROW_NUMBER()
进行比较,得到不同的结果。经观察,行号是在 ORDER BY xxx DESC
发生之前分配的。因此,从视觉上看,它确实按 date
相应地降序排序,但 rn
列 “不正确” 生成。我发现的解决方法是先在子查询中执行聚合,然后只尝试生成自定义行编号。请参阅我更新的查询和上面的 fiddle。