【问题标题】:MySQL get count of periods where date in rowMySQL获取行中日期的周期数
【发布时间】:2015-09-15 14:34:07
【问题描述】:

我有一个 MySQL 表,类似于这个例子:

c_id    date    value
66  2015-07-01  1
66  2015-07-02  777
66  2015-08-01  33
66  2015-08-20  200
66  2015-08-21  11
66  2015-09-14  202
66  2015-09-15  204
66  2015-09-16  23
66  2015-09-17  0
66  2015-09-18  231

我需要得到的是日期在行中的期间数。我没有固定的开始或结束日期,可以有。

例如:2015-07-01 - 2015-07-02 为一期,2015-08-01 为第二期,2015-08-20 - 2015-08-21 为第三期,2015-09-14 - 2015-09-18 作为第四期。所以在这个例子中有四个句点。

SELECT 
SUM(value) as value_sum,
... as period_count
FROM my_table 
WHERE cid = 66

整天都想不通。谢谢。

【问题讨论】:

  • 您是否以01.07.2015 格式保存日期?
  • 这里同样的问题[按变量范围分组][1] [1]:stackoverflow.com/questions/32585265/…
  • 没有正确的 mysql 格式的日期,例如 2015-09-18,当我复制数据时它们出错了。会修复帖子,你说清楚。
  • @AbhikChakraborty 时间段,不是标点时间段。

标签: mysql


【解决方案1】:

我没有足够的声誉来评论上述答案。

如果您只需要拆分的数量,那么您可以简单地改写您的问题:“有多少条目具有日期 D,因此日期 D - 1 DAY 没有条目?”

在这种情况下,这就是你所需要的:

SELECT 
    COUNT(*) as PeriodCount
FROM
    `periods`
WHERE
    DATE_ADD(`date`, INTERVAL - 1 DAY) NOT IN (SELECT `date` from `periods`);

在您的 PHP 中,只需从第一行中选择“PeriodCount”列。

在澄清之前,你让我研究了一些疯狂的存储过程方法:P

【讨论】:

  • 希望您早日获得 cmets 所需的声誉!是的,添加的评论是,OP 只想要 count 个句点 确实 使整个事情变得容易多了! +1
【解决方案2】:

我应该为此受到应得的抨击,但无论如何,请考虑以下...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(date DATE NOT NULL PRIMARY KEY
,value INT NOT NULL
);

INSERT INTO my_table VALUES
('2015-07-01',1),
('2015-07-02',777),
('2015-08-01',33),
('2015-08-20',200),
('2015-08-21',11),
('2015-09-14',202),
('2015-09-15',204),
('2015-09-16',23),
('2015-09-17',0),
('2015-09-18',231);

SELECT x.*
     , SUM(y.value) total
  FROM 
     ( SELECT a.date start
            , MIN(c.date) end 
         FROM my_table a
         LEFT 
         JOIN my_table b 
           ON b.date = a.date - INTERVAL 1 DAY 
         LEFT 
         JOIN my_table c   
           ON c.date >= a.date
         LEFT 
         JOIN my_table d 
           ON d.date = c.date + INTERVAL 1 DAY
        WHERE b.date IS NULL 
          AND c.date IS NOT NULL
          AND d.date IS NULL
        GROUP 
           BY a.date
     ) x
  JOIN my_table y
    ON y.date BETWEEN x.start AND x.end
 GROUP 
    BY x.start;

+------------+------------+-------+
| start      | end        | total |
+------------+------------+-------+
| 2015-07-01 | 2015-07-02 |   778 |
| 2015-08-01 | 2015-08-01 |    33 |
| 2015-08-20 | 2015-08-21 |   211 |
| 2015-09-14 | 2015-09-18 |   660 |
+------------+------------+-------+
4 rows in set (0.00 sec) -- <-- This is the number of periods

【讨论】:

  • Tnx。在过去的 30 分钟里,我一直在玩你的选择,效果很好,但不是我需要的方式。我不需要按日期拆分结果,我只需要数字 - 有多少拆分。正如@abhik-chakraborty 所说 - 我的大脑因这些连接而受伤。
【解决方案3】:

有一种更简单的方法,请参阅此处SQLfiddle

SELECT min(date) start,max(date) end,sum(value) total FROM 
 (SELECT @i:=@i+1 i,
         ROUND(Unix_timestamp(date)/(24*60*60))-@i diff,
         date,value 
  FROM tbl, (SELECT @i:=0)n WHERE c_id=66 ORDER BY date) t 
GROUP BY diff

select 将序列号和日期值之间的相同差异分组。

编辑

正如 Strawberry 所说的非常正确,我的方法有一个缺陷,当一个时期跨越一个月的变化,或者实际上是到下一年的变化。 unix_timestamp() 函数可以解决这个问题:它返回自 1970-1-1 以来的秒数,因此通过将此数字除以 24*60*60,您将得到自该特定日期以来的天数。剩下的很简单...

如果您需要计数,正如您上一条评论所述,您甚至可以做到simpler

SELECT count(distinct diff) period_count FROM 
 (SELECT @i:=@i+1 i,
         ROUND(Unix_timestamp(date)/(24*60*60))-@i diff,
         date,value 
  FROM tbl,(SELECT @i:=0)n WHERE c_id=66 ORDER BY date) t 

【讨论】:

  • 谢谢@Strawberry!是的,我一直忘记如何在 MySQL SELECT 语句中正确设置变量。在 one 语句中做所有事情要好得多。
  • 这很完美。现在我需要做的就是将它合并到我的 php 脚本中。 Tnx 每个人。
【解决方案4】:

Tnx。 @cars10 解决方案在 MySQL 中工作,但无法在 PHP 中获得周期计数。它返回 0。让它工作 tnx 到 @jarkinstall。所以我的最终选择看起来像这样:

SELECT sum(coalesce(count_tmp,coalesce(count_reserved,0))) as sum ,(SELECT COUNT(*) FROM my_table WHERE cid='.$cid.' AND DATE_ADD(date, INTERVAL - 1 DAY) NOT IN (SELECT date from my_table WHERE cid='.$cid.' AND coalesce(count_tmp,coalesce(count_reserved,0))>0)) as periods ,count(*) as count ,(min(date)) as min_date ,(max(date)) as max_date FROM my_table WHERE cid=66 AND coalesce(count_tmp,coalesce(count_reserved,0))>0 ORDER BY date;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    相关资源
    最近更新 更多