mysql - SELECT直到sum达到一个数字

时间:2017-03-23 09:50:45

标签: mysql

我需要选择记录,直到列的总数达到变量数。

我有一个查询,但不是100%。我也想看到call_date,我希望按日期顺序完成计数。

SELECT NULL AS inbound_duration, NULL AS total
  FROM dual
 WHERE (@total := 0)
 UNION
SELECT inbound_duration,  @total := @total + inbound_duration AS total
FROM `records` where calling_user = '1' and call_date LIKE '2016-05-%%' and @total < 5000 ORDER BY call_date

http://sqlfiddle.com/#!9/2e74ff

3 个答案:

答案 0 :(得分:0)

order by子句不允许在union查询内部。 要摆脱这种情况,请执行以下操作

SELECT inbound_duration,total FROM 
(       
SELECT NULL AS inbound_duration, NULL AS total,NULL AS call_date
  FROM DUAL
 WHERE (@total := 0)
 UNION
SELECT inbound_duration,  @total := @total + inbound_duration AS total,call_Date
FROM `records` 
WHERE calling_user = '1' AND call_date LIKE '2016-05-%%' AND @total < 5000 
)t
ORDER BY call_date

答案 1 :(得分:0)

您不需要union来初始化变量。你可以使用例如

select * from (
  SELECT inbound_duration, @total := @total + inbound_duration AS total
  FROM `records`, (select @total := 0) init
  where calling_user = '1' and call_date LIKE '2016-05-%%'
  ORDER BY call_date
) subq
where total-inbound_duration < 5000
order by total;

由于您的日期不是唯一的,因此您应该将主键添加到内部order by,否则您可能会得到不稳定的结果:例如:对于< 6000,结果可能包含或排除金额100,具体取决于order by call_date是否在同一日期2500行之前或之后随机放置它。

答案 2 :(得分:0)

我尝试了这个(注意:你有两行具有相同的call_date:我认为获得的订单不能是确定性的,除非你按顺序指定其他标准 - ex.inbound_duration或其他一些字段):

# DROP TABLE records;
CREATE TABLE `records` (
  `inbound_duration` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
  `call_date` datetime NOT NULL,
  `calling_user` varchar(25) COLLATE utf8_unicode_ci NOT NULL
);

INSERT INTO records
    (inbound_duration, call_date, calling_user)
VALUES
    (100, '2016-05-05 00:00:00', 1),
    (1000, '2016-05-01 00:00:00', 1),
    (900, '2016-05-03 00:00:00', 1),
    (1500, '2016-05-02 00:00:00', 1),
    (2000, '2016-05-04 00:00:00', 1),
    (2500, '2016-05-05 00:00:00', 1)
;
SELECT * FROM records  ORDER BY call_date;


 SELECT NULL AS call_date, NULL AS inbound_duration, NULL AS total
  FROM dual
 WHERE @total := 0 
 UNION ALL
SELECT call_date, inbound_duration,  @total := @total + inbound_duration AS total
 FROM (SELECT * FROM records  ORDER BY call_date) C where calling_user = '1' and call_date LIKE '2016-05-%%' and @total < 5000 

;

DROP TABLE records;

输出:

    inbound_duration    call_date   calling_user
1   1000    01.05.2016 00:00:00 1
2   1500    02.05.2016 00:00:00 1
3   900 03.05.2016 00:00:00 1
4   2000    04.05.2016 00:00:00 1
5   100 05.05.2016 00:00:00 1
6   2500    05.05.2016 00:00:00 1

    call_date   inbound_duration    total
1   01.05.2016 00:00:00 1000    1000
2   02.05.2016 00:00:00 1500    2500
3   03.05.2016 00:00:00 900 3400
4   04.05.2016 00:00:00 2000    5400