如何使用 sql 按周获取滚动数据集
How to get a rolling data set by week with sql
我有一个 sql 查询,我会 运行 得到滚动总和(或移动 window)数据集。我会 运行 每 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')
此数据将 return 旧查询(过去 7 天)同一数据点的最后 3 行,假设您今天 运行 它是 2017-01-06,但只是最后一个新查询的同一数据点上有 2 行(星期日到星期六)。
有关滚动或移动 window 的含义的更多信息,请参阅此英文堆栈交换 link。
如何在 MySQL 中编写一个查询来获取滚动数据,其中最后一个数据点是最近 7 天的数据,前一个点是前 7 天,依此类推?
我不得不多次解释您的问题,因此这个答案可能不合适。听起来您正在尝试获取显示历史上按 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;
我有一个 sql 查询,我会 运行 得到滚动总和(或移动 window)数据集。我会 运行 每 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')
此数据将 return 旧查询(过去 7 天)同一数据点的最后 3 行,假设您今天 运行 它是 2017-01-06,但只是最后一个新查询的同一数据点上有 2 行(星期日到星期六)。
有关滚动或移动 window 的含义的更多信息,请参阅此英文堆栈交换 link。
如何在 MySQL 中编写一个查询来获取滚动数据,其中最后一个数据点是最近 7 天的数据,前一个点是前 7 天,依此类推?
我不得不多次解释您的问题,因此这个答案可能不合适。听起来您正在尝试获取显示历史上按 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;