Php 在MySQL中查找自上次暂停以来的期间
我需要找到自上次暂停以来没有暂停的时间段(以天为单位)。 我有下一张桌子:Php 在MySQL中查找自上次暂停以来的期间,php,mysql,Php,Mysql,我需要找到自上次暂停以来没有暂停的时间段(以天为单位)。 我有下一张桌子: id | user | date ----------------------- 1 | 1 | 16.02.2017 1 | 1 | 15.02.2017 1 | 1 | 14.02.2017 1 | 1 | 13.02.2017 1 | 1 | 10.02.2017 最后一次暂停:2月10日至13日 无暂停的最后一个周期:4天 我试图找出白天和白天的区别,但结果总
id | user | date
-----------------------
1 | 1 | 16.02.2017
1 | 1 | 15.02.2017
1 | 1 | 14.02.2017
1 | 1 | 13.02.2017
1 | 1 | 10.02.2017
最后一次暂停:2月10日至13日
无暂停的最后一个周期:4天
我试图找出白天和白天的区别,但结果总是空的。这只是第一部分。对于第二部分,我想使用类似排名的方法,但不知道它是否有效
我计划在PHP7+MySQL 5.6中使用它 我正在尝试编写一般查询,比如
select count(distinct t1.`date`) from period t1 left join period t2 ON t2.user = t1.user and t1.`date` - INTERVAL 1 DAY = t2.date where t2.id is null
你能试一下这个查询吗,
它应该可以工作,我在几乎相同的情况下使用过它。试试这个查询。它将找到所有暂停-
SELECT curr_date, prev_date FROM (
SELECT t1.date curr_date, MAX(t2.date) prev_date FROM periods t1
LEFT JOIN periods t2
ON t1.date > t2.date
GROUP BY t1.date) t
WHERE DATEDIFF(curr_date, prev_date) > 1
结果是:
13-Feb-17 10-Feb-17
然后添加条件/限制以仅获取一行。我使用了以下示例:
create table if not exists myt(id int, dd date);
insert into myt values
(1, '2017-01-01'),
(1, '2017-01-02'),
(1, '2017-01-03'),
(1, '2017-01-04'),
(1, '2017-01-08'),
(1, '2017-01-09'),
(1, '2017-01-10');
首先,应按连续天数设置分区:
select id, dd,
if(@last_date = '1900-01-01' or datediff(dd, @last_date) = -1, @cn := @cn, @cn := +1) consecutive,
@last_date := dd
from
(select @last_date := '1900-01-01', @cn := 0) x,
(select id, dd
from myt
order by dd desc) y
;
这将返回:
+----+---------------------+-------------+
| id | dd | consecutive |
+----+---------------------+-------------+
| 1 | 10.01.2017 00:00:00 | 0 |
| 1 | 09.01.2017 00:00:00 | 0 |
| 1 | 08.01.2017 00:00:00 | 0 |
+----+---------------------+-------------+
| 1 | 04.01.2017 00:00:00 | 1 |
| 1 | 03.01.2017 00:00:00 | 1 |
| 1 | 02.01.2017 00:00:00 | 1 |
| 1 | 01.01.2017 00:00:00 | 1 |
+----+---------------------+-------------+
设置分区后,获取每个分区的最大和最小日期:
select id, min(dd) as ini, max(dd) as fin, datediff(max(dd), min(dd)) as Days
from (
select id, dd,
if(@last_date = '1900-01-01' or datediff(dd, @last_date) = -1, @cn := @cn, @cn := +1) consecutive,
@last_date := dd
from
(select @last_date := '1900-01-01', @cn := 0) x,
(select id, dd
from myt
order by dd desc) y
) z
group by consecutive
;
结果:
+----+---------------------+---------------------+------+
| id | ini | fin | Days |
+----+---------------------+---------------------+------+
| 1 | 08.01.2017 00:00:00 | 10.01.2017 00:00:00 | 2 |
+----+---------------------+---------------------+------+
| 1 | 01.01.2017 00:00:00 | 04.01.2017 00:00:00 | 3 |
+----+---------------------+---------------------+------+
选中它:此查询将返回最新的孔:
select
m.`date`,
min(m1.`date`) as next_date,
datediff(min(m1.`date`), m.`date`)+1 as diff
from
mytable m left join mytable m1
on m.`date`<m1.`date`
group by
m.`date`
having
datediff(min(m1.`date`), m.`date`)>1
order by
m.`date` desc
limit 1
以下查询:
选择MIN`date`作为开始日期,
最大“日期”作为日期结束,
最大天数与暂停天数之差,
将*+1计为无付款的期间
从…起
选择id,用户,`date`,
日期子'DATE',间隔rn天作为组日期,
DATEDIFF`date`,COALESCEprevDate,`date`AS days\u diff
从…起
选择t1.id,t1.user,t1.`date`,
@rn:=@rn+1作为rn,
选择t2.`date`
从mytable中选择t2
其中t1.id=t2.id和t1.user=t2.user和t1.`date`>t2.`date`
按“日期”下单,将限额1描述为上一个日期
从mytable中选择t1
交叉连接选择@rn:=0作为v
按“日期”订购,以t作为x
按id、用户、组日期、天数区分的组
SUMdays_diff>0
返回:
date_start date_end pause_days period_without_pays
-----------------------------------------------------
2017-02-14 2017-02-16 1 4
2017-02-13 2017-02-13 3 2
pause_days>1的行返回暂停的开始日期和天数。
pause_days=1的行返回具有连续日期的连续记录孤岛的开始/结束日期以及这些日期的计数。
注:上述查询与提供的示例数据一起使用。您可能需要稍微调整查询,以便根据实际数据的复杂性进行调整。尝试以下方法:
SET @dateDiff=NULL;SET @dateDiff2='';
SELECT diff.secondDate AS fromDate,diff.initialDate AS toDate, diff.dateDiffR FROM (
SELECT d.date AS initialDate,@dateDiff AS secondDate,IF(@dateDiff IS NULL,@dateDiff:=d.date,0) AS try,
IF(DATE(@dateDiff)!=DATE(d.date),DATEDIFF(d.date,@dateDiff),NULL) AS dateDiffR,
IF(@dateDiff!=@dateDiff2,@dateDiff2:=@dateDiff,0) AS try1,
IF(DATE(@dateDiff)!=DATE(d.date),@dateDiff:=d.date,NULL) AS assign FROM
(SELECT b.date FROM mytable b)d ) diff WHERE diff.dateDiffR>0
它将为您提供日期差异及其日期范围。如果计数为负数,则将参数“上的日期”替换为DATEDIFF 代表OP发布
我改编了@McNets的小查询:
select user, min(dd) as ini, max(dd) as fin, datediff(max(dd), min(dd))+1 as Days, consecutive
from (
select user,dd,
if(@last_date = curdate() or datediff(dd, @last_date) >= -1, @cn := @cn, @cn := @cn+1) consecutive,
@last_date := dd
from
(select @last_date := curdate(), @cn := 0) x,
(select user, date as dd
from myt
where user = %id
order by dd desc) y
) z
group by consecutive
order by CAST(consecutive AS UNSIGNED)
我添加了按用户筛选,将原因更改为'>=-1'以接受时间使用,添加了序列号,并将初始日期从'1900-01-01'更改为CURDATE函数。我看不到此操作对查询结果有任何影响
现在,使用序列号可以找到最长的序列及其日期。您是指连续的日期吗?@McNets是的,rightSee刚刚发现这一点,希望它能起作用,但不会显示用户现在是否处于暂停状态。