Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在MySQL中查找自上次暂停以来的期间_Php_Mysql - Fatal编程技术网

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刚刚发现这一点,希望它能起作用,但不会显示用户现在是否处于暂停状态。