【问题标题】:How to get a rolling data set by week with sql如何使用sql按周获取滚动数据集
【发布时间】:2017-05-21 08:20:15
【问题描述】:

我有一个要运行的 sql 查询,它会得到一个滚动总和(或移动窗口)数据集。我将每 7 天运行一次此查询,将间隔数增加 7(在下面的示例中为 28),直到到达数据的开头。它会给我按周拆分的数据,以便我可以在视图上循环遍历它以创建每周图表。

  SELECT *
  FROM `table`
  WHERE `row_date` >= DATE_SUB(NOW(), INTERVAL 28 DAY)
  AND `row_date` <= DATE_SUB(NOW(), INTERVAL 28 DAY)

一旦您拥有数周的数据,这当然会非常缓慢。我想用一个查询替换它。我想出了这个。

  SELECT *
  CONCAT(YEAR(row_date), '/', WEEK(row_date)) as week_date
  FROM `table`
  GROUP BY week_date
  ORDER BY row_date DESC

它看起来基本准确,但我注意到 2015 年的本周和最后一周比平时低得多。这是因为此查询从星期日(或星期一?)开始一周,这意味着它每周都会重置。

这是一个员工数据集,您可以使用它来展示行为。

CREATE TABLE employees (
    id          INT             NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    row_date    DATE            NOT NULL,
    PRIMARY KEY (id)
);

INSERT INTO `employees` VALUES
(1,'Bezalel','Simmel','2016-12-25'),
(2,'Bezalel','Simmel','2016-12-31'),
(3,'Bezalel','Simmel','2017-01-01'),
(4,'Bezalel','Simmel','2017-01-05')

假设您在 2017 年 1 月 6 日今天运行,此数据将返回旧查询(过去 7 天)同一数据点的最后 3 行,但新查询仅返回同一数据点的最后 2 行查询(周日到周六)。

有关滚动或移动窗口的含义的更多信息,请参阅此英文堆栈交换链接。

https://english.stackexchange.com/questions/362791/word-for-graph-that-counts-backwards-vs-graph-that-counts-forwards

如何在 MySQL 中编写一个查询,它会为我带来滚动数据,其中最后一个数据点是最近 7 天的数据,前一个点是前 7 天,依此类推?

【问题讨论】:

  • 鉴于您的查询,您为什么不能只做select * from order`?什么是“滚动数据集”?
  • 返回按周分组的数据。这样我就可以每周绘制它。我会尽量澄清这个问题。
  • @Strawberry 好点。我可以提供确切的数据集或结构,但我编辑了我的答案以展示如何证明这个问题。
  • @Strawberry 我已经用一个真实的数据集更新了这个问题,可以用来证明这个问题。
  • 这不只是来自sink.agiletoolkit.org/employees 的完整数据集吗?我可以建议提供一个明显小于 17MB 的示例数据集以及一些示例 SELECT 查询/数据集。不完全确定您对开始/结束周还有什么期望,因为它们通常不包含 7 天,因此它们的总和会更小。

标签: mysql sql database dataset


【解决方案1】:

我不得不对您的问题进行很多解释,因此此答案可能不合适。听起来您正试图获得一个图表,显示历史上按 7 天时间分组的数据。您当前的尝试是通过按日历周而不是按 7 天分组来实现这一点,从而导致周期大小不一致。

所以在 sql fiddle (http://sqlfiddle.com/#!9/90f1f2) 上使用你的数据集的修改我想出了这个

  SELECT 
    -- Figure out how many periods of 7 days ago this record applies to
    FLOOR( DATEDIFF( CURRENT_DATE , row_date ) / 7 ) AS weeks_ago,
    -- Count the number of ids in this group
    COUNT( DISTINCT id ) AS number_in_week,
    -- Because this is grouped, make sure to have some consistency on what we select instead of leaving it to chance
    MIN( row_date ) AS min_date_in_week_in_dataset 
  FROM `sample_data`
  -- Groups by weeks ago because that's what you are interested in
  GROUP BY weeks_ago
  ORDER BY 
    min_date_in_week_in_dataset DESC;

【讨论】:

  • 查询给了我奇怪的结果。 weeks_ago 是否应该返回分数?
  • 啊,使用 floor,如 floor(DATEDIFF( CURRENT_DATE , order_date ) / 7) AS weeks_ago 会导致我期待的确切行为。如果您同意,请将其编辑到您的问题中,我很乐意接受。你们一直很有耐心。
  • 抱歉 - 我忘了用我的 sqlfiddle 中的查询更新我的答案。为了将来参考,使用 SQL fiddle 提供再现标准,以及您希望数据看起来的文本表示形式,可能比尝试描述它更容易!
猜你喜欢
  • 2016-10-07
  • 2016-07-07
  • 2020-07-14
  • 1970-01-01
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
相关资源
最近更新 更多