SQL:如何每天选择多条记录,假设每天包含超过1个值,MySQL

Posted

技术标签:

【中文标题】SQL:如何每天选择多条记录,假设每天包含超过1个值,MySQL【英文标题】:SQL: How to select multiple records per day, assuming that each day contain more than 1 value, MySQL 【发布时间】:2015-12-23 09:44:01 【问题描述】:

所以我有一个巨大的表,其中包含每天的多条记录。我想每天获得 5 或 10 条记录。每行都有 created_at 字段,时间戳格式示例:2015-01-01 00:00:01。并且每一行都有一个唯一的 ID 字段。

使用 mysql 5.5.44

我找到了这个 (SQL: How to select one record per day...):

select * from value_magnitudes
where id in 
(
    SELECT min(id)
    FROM value_magnitudes
    WHERE magnitude_id = 234
    and date(reading_date) >= '2013-04-01'
    group by date(reading_date)
)

它每天给我一个记录。我尝试了几次来修改它以满足我的需要,但我想它不能用那个简单的查询来完成。

然后我发现了这个(How to select more than 1 record per day?):

SELECT date_time, other_column
FROM  (
   SELECT *, row_number() OVER (PARTITION BY date_time::date) AS rn
   FROM   tbl
   WHERE  date_time >= '2012-11-01 0:0'
   AND    date_time <  '2012-12-01 0:0'
   ) x
WHERE  rn < 4;

无法让这个工作(当然更改了字段的名称)。它给了我这个错误:

您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,了解在 '(PARTITION BY created_at::date) AS rn 附近使用的正确语法 来自 tbl WHERE created_at >= '201' 在第 3 行

那么请你们给我指出正确的方向。

更新: 期望的结果看起来像这样(同一日期只有两个,但你明白了):

id                                      company_id                          created_at
0001c73d-8f95-49b8-a380-275c3863974d    90f87a37-801f-4f05-b86d-b25574aa457d    2015-12-01 22:36:20
000074d3-0116-4d13-bea9-7256d522ea88    53171f70-7b65-4e17-a222-8d9952351b88    2015-12-01 14:09:19
00002a24-c14a-4584-8657-ad62a62d8bb2    ad83edbc-fe82-443f-96fb-8188b91fdd62    2015-12-02 09:15:22
000023b7-9a32-4ac9-9f8d-e18712c0a940    3713bc34-bffa-458d-98bc-266acfcacc6c    2015-12-02 14:57:24
0000d51e-dea7-446c-9974-4536501d77ec    23d1556c-0719-4260-9740-a8882badf2db    2015-12-03 13:19:22
0020e450-866f-4467-b5fe-892d1b9565a0    90f87a37-801f-4f05-b86d-b25574aa677d    2015-12-03 13:46:01
00001bc4-6d39-494c-8b4c-43050ebe537e    90f87a37-801f-4f05-b86d-b25574aa478d    2015-12-04 22:09:50
000035cf-409f-4cfb-adcd-412eb5def840    90f87a37-801f-4f05-b86d-b25574aa434d    2015-12-04 22:50:43

INSERT 就像这样:

INSERT INTO `invoices` (`id`, `company_id`, `created_at`)
VALUES
    ('0001c73d-8f95-49b8-a380-275c3863974d', '90f87a37-801f-4f05-b86d-b25574aa457d', '2015-12-01 22:36:20'),
    ('000074d3-0116-4d13-bea9-7256d522ea88', '53171f70-7b65-4e17-a222-8d9952351b88', '2015-12-01 14:09:19'),
    ('00002a24-c14a-4584-8657-ad62a62d8bb2', 'ad83edbc-fe82-443f-96fb-8188b91fdd62', '2015-12-02 09:15:22'),
    ('000023b7-9a32-4ac9-9f8d-e18712c0a940', '3713bc34-bffa-458d-98bc-266acfcacc6c', '2015-12-02 14:57:24'),
    ('0000d51e-dea7-446c-9974-4536501d77ec', '23d1556c-0719-4260-9740-a8882badf2db', '2015-12-03 13:19:22'),
    ('0020e450-866f-4467-b5fe-892d1b9565a0', '90f87a37-801f-4f05-b86d-b25574aa677d', '2015-12-03 13:46:01'),
    ('00001bc4-6d39-494c-8b4c-43050ebe537e', '90f87a37-801f-4f05-b86d-b25574aa478d', '2015-12-04 22:09:50'),
    ('000035cf-409f-4cfb-adcd-412eb5def840', '90f87a37-801f-4f05-b86d-b25574aa434d', '2015-12-04 22:50:43');

【问题讨论】:

如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更容易复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。 更新了所需的结果并为此插入。希望人们明白这一点。 【参考方案1】:

您可以使用变量来获取结果集的行号,因为 mysql 不支持 ROWNUM 作为 oracle。 请试试这个:

select * 
from (
    select id,date(date_time) as date_time,other_columns,
    case when @date = date(date_time) then 
        @rn := @rn + 1 
    else 
        @rn := 1 
    end as x, -- row numbers for each date_time
    @date := date(date_time)
    from your_table
    inner join(select @date := '', @rn:=1) as tmp
    order by date(date_time) asc
) as tbl
where x <= 5 --5 records for each date_time

上面的查询将为您提供每天 5 条记录(如果有)。

【讨论】:

我想这可以工作,但我正在研究一个只读从站,所以我不能写 tmp。 @Taapsa 对不起,你是什么意思 我正在做一个只读从站,所以我不能写 tmp 当我运行该查询时出现错误:写入文件时出错'/tmp/MYhvHybc' (Errcode: 28) 或者我在这里做错了什么。我更改了 date_time 以匹配我的 table = created_at 并且我假设我可以在这里给出所需的时间跨度:“ inner join(select @date := ' ' ''? @Taapsa 不,@date 是可变的,你不能在那里给出所需的时间跨度。您可以在子查询...) as tmp where create_at between :from and :to order by date(date_time)... 中添加 where 子句

以上是关于SQL:如何每天选择多条记录,假设每天包含超过1个值,MySQL的主要内容,如果未能解决你的问题,请参考以下文章

选择一个Id每天的最新记录 - Oracle pl sql

SQL:如何每天选择一行

选择具有每天每条记录的创建顺序的行

SQL递归添加日期,直到数据集每天有一条记录

bash脚本通过每天保留1个备份来删除超过7天的备份[重复]

sql题 如何统计查询一个月中每天的记录