我一直在寻找这个,但所有类似的问题和答案都是不同的,不适用。
我有一个包含以下字段的表:person,thing,purdate。当一个人购买每件新东西时,就会输入一条新记录。
我想计算一个人买了任何“东西”的连续月份(thing01或者thing02,它并不重要)。如果连续的purdays中断,那么计数应该重新开始。
随附数据,我想最终得到这个:
| Person | Consec Days |
| person_01 | 3 |
| person_02 | 3 |
| person_02 | 2 |
我知道我可以获得一个明确的人员列表,提取(来自purdate的year_month) - 这是我在SQLFIDDLE中完成的 - 但我不知道如何只计算连续记录并在休息时重新开始(就像在我的数据中,person_02在3月到5月之间中断。)
以下是数据:
create table records (
person varchar(32) not null,
thing varchar(32) not null,
purdate datetime not null
);
insert into records (person, thing, purdate) values
('person_01', 'thing01', '2014-01-02'),
('person_01', 'thing02', '2014-01-02'),
('person_01', 'thing02', '2014-02-27'),
('person_01', 'thing02', '2014-03-27'),
('person_02', 'thing02', '2014-01-28'),
('person_02', 'thing01', '2014-02-28'),
('person_02', 'thing02', '2014-03-28'),
('person_02', 'thing02', '2014-05-29'),
('person_02', 'thing02', '2014-06-29')
;
答案 0 :(得分:5)
您可以使用变量(或非常复杂的相关子查询)在MySQL中执行此操作。在其他数据库中,您将使用窗口/分析函数。
逻辑是:
这是一个已在SQL小提琴上测试的查询:
select person, count(*) as numMonths
from (select person, ym, @ym, @person,
if(@person = person and @ym = ym - 1, @grp, @grp := @grp + 1) as grp,
@person := person,
@ym := ym
from (select distinct person, year(purdate)*12+month(purdate) as ym
from records r
) r cross join
(select @person := '', @ym := 0, @grp := 0) const
order by 1, 2
) pym
group by person, grp;
答案 1 :(得分:3)
我使用此StackOverflow答案作为指导(Check for x consecutive days - given timestamps in database)
SELECT a.person, COUNT(1) AS consecutive_months
FROM
(
SELECT a.person, IF(b.YearMonth IS NULL, @val:=@val+1, @val) AS consec_set
FROM (
SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records
) a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN (SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records) b ON
a.person = b.person AND
a.YearMonth = b.YearMonth + 1
) a
GROUP BY a.consec_set
HAVING COUNT(1) >= 2
这是SQLFiddle - http://sqlfiddle.com/#!2/cc5c3/55