为每个日期选择行的子集
Selecting a subset of rows for each date
我在 MySQL 数据库中有一个 table,其中包含事件。
我需要 select 一个月的活动(例如从 12 月 10 日到 1 月 10 日),每天限制 5 个活动。 (事件时间存储为时间戳)。
我可以用一个查询来实现吗?还是我必须启动 30 个不同的查询?
您似乎想要 greatest_n_per_group
。此站点上有一个 tag。
对于此示例,如果每天有超过 5 个事件,您没有指定要 select 哪 5 个事件。对于我的示例,假设您想要 select 当天具有 5 个最高 ID 的事件。我把运行下面改成SQLFiddle:
CREATE TABLE events(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
eventDate DATE);
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
如果您数一数,12 月 10 日(ID 1-6)发生了 6 起事件,12 月 15 日发生了 5 起事件(ID 7-11),12 月 20 日发生了 3 起事件(ID 12-14)。
根据我的预期输出,对于 12 月 10 日的事件,我应该只会看到 ID 2-6,而在其他两天会看到所有事件。这可以通过以下查询来完成:
SELECT *
FROM events e
WHERE (SELECT COUNT(*)
FROM events ev
WHERE ev.eventDate = e.eventDate AND ev.id >= e.id) <= 5
AND e.eventDate BETWEEN '2014-12-10' AND '2015-01-10';
这类似于自连接,查看每个日期,并通过 selecting 最大的 id(由条件 ev.id >= e.id
完成)进行过滤,只要行数为每个日期不超过5个。
这是一个 SQL Fiddle 示例。
我在 MySQL 数据库中有一个 table,其中包含事件。
我需要 select 一个月的活动(例如从 12 月 10 日到 1 月 10 日),每天限制 5 个活动。 (事件时间存储为时间戳)。
我可以用一个查询来实现吗?还是我必须启动 30 个不同的查询?
您似乎想要 greatest_n_per_group
。此站点上有一个 tag。
对于此示例,如果每天有超过 5 个事件,您没有指定要 select 哪 5 个事件。对于我的示例,假设您想要 select 当天具有 5 个最高 ID 的事件。我把运行下面改成SQLFiddle:
CREATE TABLE events(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
eventDate DATE);
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-10');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-15');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
INSERT INTO events (eventDate) VALUES ('2014-12-20');
如果您数一数,12 月 10 日(ID 1-6)发生了 6 起事件,12 月 15 日发生了 5 起事件(ID 7-11),12 月 20 日发生了 3 起事件(ID 12-14)。
根据我的预期输出,对于 12 月 10 日的事件,我应该只会看到 ID 2-6,而在其他两天会看到所有事件。这可以通过以下查询来完成:
SELECT *
FROM events e
WHERE (SELECT COUNT(*)
FROM events ev
WHERE ev.eventDate = e.eventDate AND ev.id >= e.id) <= 5
AND e.eventDate BETWEEN '2014-12-10' AND '2015-01-10';
这类似于自连接,查看每个日期,并通过 selecting 最大的 id(由条件 ev.id >= e.id
完成)进行过滤,只要行数为每个日期不超过5个。
这是一个 SQL Fiddle 示例。