求教一条SQL语句的写法

nightgoblin 2016-07-27 06:29:54
目前有这样一张表
源码:

DROP TABLE IF EXISTS t_g;
CREATE TABLE t_g
(t_id BIGINT AUTO_INCREMENT,
t_userid VARCHAR(10) DEFAULT '' COMMENT '用户id',
t_je VARCHAR(10) DEFAULT '' COMMENT '交易金额',
t_date VARCHAR(20) DEFAULT '' COMMENT '交易时间',
PRIMARY KEY(t_id)
);

INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','20','20160701');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','10','20160702');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','15','20160703');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','15','20160704');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','20','20160705');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','50','20160706');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','20','20160707');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('A','20','20160708');

INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('B','40','20160701');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('B','20','20160702');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('B','15','20160703');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('B','15','20160704');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('C','20','20160701');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('C','50','20160702');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('C','20','20160703');
INSERT INTO t_g (t_userid,t_je,t_date) VALUES ('C','20','20160704');


现在需要查询这样一个条件,当每个用户交易金额累计达到70时的交易时间,这样的语句怎样写啊,例如:
用户A的数据
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date |
+------+----------+------+----------+
| 1 | A | 20 | 20160701 |
| 2 | A | 10 | 20160702 |
| 3 | A | 15 | 20160703 |
| 4 | A | 15 | 20160704 |
| 5 | A | 20 | 20160705 |
| 6 | A | 50 | 20160706 |
| 7 | A | 20 | 20160707 |
| 8 | A | 20 | 20160708 |
+------+----------+------+----------+

当t_id=5时,累计金额为80 超过了70,这时交易时间为20160705,就是要把这个交易时间查出来,请问高手们怎么写啊??
...全文
176 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
丶小飞哥 2016-07-29
  • 打赏
  • 举报
回复
引用 13 楼 DOTAER_AND_DBA 的回复:
[quote=引用 12 楼 u013397297 的回复:] [quote=引用 9 楼 DOTAER_AND_DBA 的回复:] [quote=引用 3 楼 zjcxc 的回复:] 这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
有个地方没看懂,请教一下 为什么select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date这个子查询不用group by分组,最后就能求每个用户?[/quote] 所用的@sum在每次查询中都是同一个值,所以并不需要分组,查询出来的是一条条记录,不涉及分组 [/quote] 子查询的sum如果不分组,算出来的就是表自关联之后所有用户的金额的总和 [/quote] 不是呀,c.t_userid=a.t_userid,结果是 相同用户的金额总和
  • 打赏
  • 举报
回复
引用 12 楼 u013397297 的回复:
[quote=引用 9 楼 DOTAER_AND_DBA 的回复:] [quote=引用 3 楼 zjcxc 的回复:] 这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
有个地方没看懂,请教一下 为什么select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date这个子查询不用group by分组,最后就能求每个用户?[/quote] 所用的@sum在每次查询中都是同一个值,所以并不需要分组,查询出来的是一条条记录,不涉及分组 [/quote] 子查询的sum如果不分组,算出来的就是表自关联之后所有用户的金额的总和
丶小飞哥 2016-07-29
  • 打赏
  • 举报
回复
引用 9 楼 DOTAER_AND_DBA 的回复:
[quote=引用 3 楼 zjcxc 的回复:]
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
and @sum - a.t_je <= 70
;

有个地方没看懂,请教一下
为什么select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date这个子查询不用group by分组,最后就能求每个用户?[/quote]
所用的@sum在每次查询中都是同一个值,所以并不需要分组,查询出来的是一条条记录,不涉及分组
丶小飞哥 2016-07-29
  • 打赏
  • 举报
回复
引用 4 楼 nightgoblin 的回复:
[quote=引用 2 楼 ACMAIN_CHM 的回复:]
mysql> select * from t_g;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date |
+------+----------+------+----------+
| 1 | A | 20 | 20160701 |
| 2 | A | 10 | 20160702 |
| 3 | A | 15 | 20160703 |
| 4 | A | 15 | 20160704 |
| 5 | A | 20 | 20160705 |
| 6 | A | 50 | 20160706 |
| 7 | A | 20 | 20160707 |
| 8 | A | 20 | 20160708 |
| 9 | B | 40 | 20160701 |
| 10 | B | 20 | 20160702 |
| 11 | B | 15 | 20160703 |
| 12 | B | 15 | 20160704 |
| 13 | C | 20 | 20160701 |
| 14 | C | 50 | 20160702 |
| 15 | C | 20 | 20160703 |
| 16 | C | 20 | 20160704 |
+------+----------+------+----------+
16 rows in set (0.00 sec)

mysql> select *
-> from t_g t
-> where (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)<70
-> and (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)>=70-t.t_je;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date |
+------+----------+------+----------+
| 5 | A | 20 | 20160705 |
| 11 | B | 15 | 20160703 |
| 14 | C | 50 | 20160702 |
+------+----------+------+----------+
3 rows in set (0.00 sec)

mysql>
能说说思路么[/quote]

这个写法思路是,在所有sum累加小于等于70的小值里面,取出最大值的交易时间,查询结果可以满足你的需求。
当然优化一下更好:

这是我总结了一下他们两位大牛的结果,真的长见识了
丶小飞哥 2016-07-29
  • 打赏
  • 举报
回复
引用 5 楼 nightgoblin 的回复:
[quote=引用 3 楼 zjcxc 的回复:]
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
and @sum - a.t_je <= 70
;
能说说思路吗[/quote]

这个思路是,在sum累加后大于70的所有值里面,取出最小值的交易时间。

这张图片内容,有助于你理解。
其实,这个思路是错误的,在大值里面取最小值,导致跳过了临界值,当sum=70的时候,直接跳到下一项结果数据了,数据C的结果就是这样
nightgoblin 2016-07-28
  • 打赏
  • 举报
回复
引用 3 楼 zjcxc 的回复:
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
能说说思路吗
nightgoblin 2016-07-28
  • 打赏
  • 举报
回复
引用 2 楼 ACMAIN_CHM 的回复:
mysql> select * from t_g;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    1 | A        | 20   | 20160701 |
|    2 | A        | 10   | 20160702 |
|    3 | A        | 15   | 20160703 |
|    4 | A        | 15   | 20160704 |
|    5 | A        | 20   | 20160705 |
|    6 | A        | 50   | 20160706 |
|    7 | A        | 20   | 20160707 |
|    8 | A        | 20   | 20160708 |
|    9 | B        | 40   | 20160701 |
|   10 | B        | 20   | 20160702 |
|   11 | B        | 15   | 20160703 |
|   12 | B        | 15   | 20160704 |
|   13 | C        | 20   | 20160701 |
|   14 | C        | 50   | 20160702 |
|   15 | C        | 20   | 20160703 |
|   16 | C        | 20   | 20160704 |
+------+----------+------+----------+
16 rows in set (0.00 sec)

mysql> select *
    -> from t_g t
    -> where (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)<70
    -> and (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)>=70-t.t_je;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    5 | A        | 20   | 20160705 |
|   11 | B        | 15   | 20160703 |
|   14 | C        | 50   | 20160702 |
+------+----------+------+----------+
3 rows in set (0.00 sec)

mysql>
能说说思路么
zjcxc 2016-07-28
  • 打赏
  • 举报
回复
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
  • 打赏
  • 举报
回复
引用 3 楼 zjcxc 的回复:
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
有个地方没看懂,请教一下 为什么select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date这个子查询不用group by分组,最后就能求每个用户?
  • 打赏
  • 举报
回复
引用 3 楼 zjcxc 的回复:
这种写法比较变态
select * from t_g a
where (select @sum:=sum(t_je) from t_g c where c.t_userid=a.t_userid and c.t_date <= a.t_date) > 70
	and @sum - a.t_je <= 70
;
确实变态
  • 打赏
  • 举报
回复
引用 1 楼 zhangbin1988 的回复:

select * from
(
	select *,(select sum(t_je) from t_g where t_userid = a.t_userid and t_date <= a.t_date)total from t_g a where a.t_userid = 'A'
)x where x.total > 70 order by x.total asc limit 1;
//希望楼下有更好的
这只是求a的,没有算每个用户的
nightgoblin 2016-07-28
  • 打赏
  • 举报
回复
引用 2 楼 ACMAIN_CHM 的回复:
mysql> select * from t_g;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    1 | A        | 20   | 20160701 |
|    2 | A        | 10   | 20160702 |
|    3 | A        | 15   | 20160703 |
|    4 | A        | 15   | 20160704 |
|    5 | A        | 20   | 20160705 |
|    6 | A        | 50   | 20160706 |
|    7 | A        | 20   | 20160707 |
|    8 | A        | 20   | 20160708 |
|    9 | B        | 40   | 20160701 |
|   10 | B        | 20   | 20160702 |
|   11 | B        | 15   | 20160703 |
|   12 | B        | 15   | 20160704 |
|   13 | C        | 20   | 20160701 |
|   14 | C        | 50   | 20160702 |
|   15 | C        | 20   | 20160703 |
|   16 | C        | 20   | 20160704 |
+------+----------+------+----------+
16 rows in set (0.00 sec)

mysql> select *
    -> from t_g t
    -> where (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)<70
    -> and (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)>=70-t.t_je;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    5 | A        | 20   | 20160705 |
|   11 | B        | 15   | 20160703 |
|   14 | C        | 50   | 20160702 |
+------+----------+------+----------+
3 rows in set (0.00 sec)

mysql>
我试了下你这个写法,好慢啊,我表里面有30多万数据,结果很长时间才能运行出来
ACMAIN_CHM 2016-07-27
  • 打赏
  • 举报
回复
mysql> select * from t_g;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    1 | A        | 20   | 20160701 |
|    2 | A        | 10   | 20160702 |
|    3 | A        | 15   | 20160703 |
|    4 | A        | 15   | 20160704 |
|    5 | A        | 20   | 20160705 |
|    6 | A        | 50   | 20160706 |
|    7 | A        | 20   | 20160707 |
|    8 | A        | 20   | 20160708 |
|    9 | B        | 40   | 20160701 |
|   10 | B        | 20   | 20160702 |
|   11 | B        | 15   | 20160703 |
|   12 | B        | 15   | 20160704 |
|   13 | C        | 20   | 20160701 |
|   14 | C        | 50   | 20160702 |
|   15 | C        | 20   | 20160703 |
|   16 | C        | 20   | 20160704 |
+------+----------+------+----------+
16 rows in set (0.00 sec)

mysql> select *
    -> from t_g t
    -> where (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)<70
    -> and (select sum(t_je) from t_g where t_userid=t.t_userid and t_date<t.t_date)>=70-t.t_je;
+------+----------+------+----------+
| t_id | t_userid | t_je | t_date   |
+------+----------+------+----------+
|    5 | A        | 20   | 20160705 |
|   11 | B        | 15   | 20160703 |
|   14 | C        | 50   | 20160702 |
+------+----------+------+----------+
3 rows in set (0.00 sec)

mysql>
ayzen1988 2016-07-27
  • 打赏
  • 举报
回复

select * from
(
	select *,(select sum(t_je) from t_g where t_userid = a.t_userid and t_date <= a.t_date)total from t_g a where a.t_userid = 'A'
)x where x.total > 70 order by x.total asc limit 1;
//希望楼下有更好的

56,679

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧