【问题标题】:Get database records which are within a specific timeframe获取特定时间范围内的数据库记录
【发布时间】:2016-04-26 10:18:19
【问题描述】:

假设我有一个名为video_data 的表格。我还有一个videos,但它并不真正相关。我用它来查询特定频道的视频,但这不会改变查询。只是获取一个通道而不是所有通道的计算。

+----+----------+-------+---------------------+
| id | video_id | views |     created_at      |
+----+----------+-------+---------------------+
|  1 |        1 |  1000 | 2016-04-26 00:00:00 |
|  2 |        2 |   500 | 2016-04-26 00:00:01 |
|  3 |        3 |  2500 | 2016-04-26 00:00:02 |

|  4 |        1 |  1500 | 2016-04-26 02:00:00 |
|  5 |        2 |  1000 | 2016-04-26 02:00:01 |
|  6 |        3 |  3000 | 2016-04-26 02:00:02 |

|  7 |        1 |  5000 | 2016-04-26 04:00:00 |
|  8 |        2 | 10000 | 2016-04-26 04:00:01 |
|  9 |        3 | 30000 | 2016-04-26 04:00:02 |
+----+----------+-------+---------------------+

我现在要做的是获取时间范围内的平均观看次数。假设,我想获得一个视频在 2 小时内的平均观看次数。让我们以video_ 1 的视频为例进行此操作

所以我需要做的是以下。我需要得到id: 1id: 4 的平均值。这将是1250,因为它是(1000 + 1500) / 2。接下来我需要得到id: 4id: 7 的平均值。这将是3250,因为它是(1500 + 5000) / 2。现在视频在两个小时内的平均播放量是2250,因为它是(1250 + 3250) / 2,对吗?

现在我不知道如何从 MySQL 获取它。甚至可以用普通的 MySQL 做吗?我需要很多很多video_data。就像我有超过 100 小时的数据一样!如果id: 100id: 105 的数据彼此相隔不到两个小时,我仍然需要计算这些数据以进行计算。

我想以某种方式这样做

select *
from `video_data`
where `video_id` in (select `id` from `videos` where `channel_id` = 1)
  and TIMEDIFF(`created_at`, `created_at`) < '02:00:00'

但这只是返回我所有的结果,因为TIMEDIFF 的结果总是00:00:00

我为此创建了一个SQL Fiddle

MySQL 5.6 架构设置

CREATE TABLE `video_data` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `video_id` int(10) unsigned NOT NULL,
  `shares` int(11) DEFAULT NULL,
  `likes` int(11) DEFAULT NULL,
  `comments` int(11) DEFAULT NULL,
  `total_count` int(11) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `video_data` (`id`, `video_id`, `shares`, `likes`, `comments`, `total_count`, `created_at`, `updated_at`)
VALUES
    (1889612, 245721, 777, 69922, 1314, 72013, '2015-10-04 20:00:04', '2015-10-04 20:00:04'),
    (1896986, 245721, 970, 90611, 1570, 93151, '2015-10-04 21:00:04', '2015-10-04 21:00:04'),
    (1904145, 245721, 1121, 104636, 1725, 107482, '2015-10-04 22:00:05', '2015-10-04 22:00:05'),
    (1911872, 245721, 1199, 115389, 1838, 118426, '2015-10-04 23:00:04', '2015-10-04 23:00:04'),
    (1882621, 245007, 1651, 102569, 2659, 106879, '2015-10-04 19:00:06', '2015-10-04 19:00:06'),
    (1889613, 245007, 1769, 113910, 2775, 118454, '2015-10-04 20:00:05', '2015-10-04 20:00:05'),
    (1896988, 245007, 1829, 121646, 2851, 126326, '2015-10-04 21:00:05', '2015-10-04 21:00:05'),
    (1904150, 245007, 1889, 127677, 2917, 132483, '2015-10-04 22:00:06', '2015-10-04 22:00:06'),
    (1911877, 245007, 1914, 132764, 2957, 137635, '2015-10-04 23:00:05', '2015-10-04 23:00:05'),
    (1845984, 239950, 675, 75030, 1373, 77078, '2015-10-04 12:00:04', '2015-10-04 12:00:04'),
    (1849749, 239950, 857, 97028, 1617, 99502, '2015-10-04 13:00:05', '2015-10-04 13:00:05'),
    (1853996, 239950, 1021, 113648, 1801, 116470, '2015-10-04 14:00:04', '2015-10-04 14:00:04'),
    (1858726, 239950, 1148, 126624, 1919, 129691, '2015-10-04 15:00:04', '2015-10-04 15:00:04'),
    (1863954, 239950, 1297, 137950, 2019, 141266, '2015-10-04 16:00:04', '2015-10-04 16:00:04'),
    (1869723, 239950, 1427, 148069, 2102, 151598, '2015-10-04 17:00:04', '2015-10-04 17:00:04'),
    (1875982, 239950, 1549, 156391, 2194, 160134, '2015-10-04 18:00:05', '2015-10-04 18:00:05'),
    (1882622, 239950, 1618, 161312, 2232, 165162, '2015-10-04 19:00:07', '2015-10-04 19:00:07'),
    (1889616, 239950, 1683, 164783, 2261, 168727, '2015-10-04 20:00:06', '2015-10-04 20:00:06'),
    (1896990, 239950, 1722, 167718, 2278, 171718, '2015-10-04 21:00:06', '2015-10-04 21:00:06'),
    (1904151, 239950, 1743, 170240, 2290, 174273, '2015-10-04 22:00:07', '2015-10-04 22:00:07'),
    (1911880, 239950, 1761, 172363, 2300, 176424, '2015-10-04 23:00:06', '2015-10-04 23:00:06');

当我现在执行查询时

select avg(pd.shares) AS shares, avg(pd.likes) AS likes, avg(pd.comments) AS comments FROM video_data pd JOIN video_data pd1 ON pd1.video_id = pd.`video_id` AND TIMEDIFF(pd.created_at, pd1.created_at) <= '02:00:00';

+-----------+-------------+-----------+
|  shares   |    likes    | comments  |
+-----------+-------------+-----------+
| 1298.2077 | 123542.5769 | 2032.2769 |
+-----------+-------------+-----------+

但是在查看结果时,likes 的值似乎是数据库中 ALL 喜欢的平均值,而不仅仅是相隔仅 2 小时的那些,对吧?还是正确的?

【问题讨论】:

  • “正确吗?”我们怎么知道?
  • id 4 和 id 7 似乎是同一日期的同一视频,所以我很困惑为什么它们会是单独的行。
  • 没有channel_id,也没有明确说明时间范围是如何定义的。
  • 我加了解释
  • 仍然没有channel_id。这很混乱。

标签: php mysql sql


【解决方案1】:
select t.*,avg(t1.views) from videos t join videos t1 on
t1.video_id=t.video_id 
and timediff(t.created_at,t1.created_at)< '02:00:00' 
group by t.video_id

试试这个查询它应该可以工作

【讨论】:

  • 错字:created_at 不是crated_at
  • 将改变它@MarcinOrlowski
  • 请稍等,我会尝试检查是否返回正确的值
  • 这肯定遗漏了一条重要信息
  • @Musterknabe 我添加了一个 group by 子句,看看这是否适合你,它会将值分组并给出特定 video_id 的结果
【解决方案2】:

但这只是返回我每个结果,因为 TIMEDIFF 的结果总是 00:00:00

这样做是因为您使用了同一列:

TIMEDIFF(`created_at`, `created_at`)

所以几乎不可能让它产生不同的结果。您可能想使用NOW() 作为参数之一?

【讨论】:

  • 我明白这一点。这只是我如何尝试获得结果但失败的一个例子。 NOW() 不起作用,因为 video_data 可能有 10 和 12 小时的历史,并且仍然需要计算,因为这两个数据有 2 小时的时差。
  • @MarcinOrlowski 你是绝对正确的,但没有回答问题
猜你喜欢
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 2012-03-23
  • 2021-04-17
  • 2013-09-12
相关资源
最近更新 更多