【问题标题】:How to select array of rows with max param from each range?如何从每个范围中选择具有最大参数的行数组?
【发布时间】:2015-08-25 11:49:17
【问题描述】:

我有这样的 sqlite 表:

CREATE TABLE "table" (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    `param` REAL NOT NULL,
    `date`  INTEGER NOT NULL
);

INSERT INTO table (param , date) VALUES (123.3, 1427824800 );
INSERT INTO table (param , date) VALUES (122.3, 1427825800 );
INSERT INTO table (param , date) VALUES (125.0, 1427652000 );
INSERT INTO table (param , date) VALUES (123.9, 1427652900);


|id| param | date       |
|==|=======|============|
| 1| 123.3 | 1427824800 |
| 2| 122.3 | 1427825800 |
| 3| 125   | 1427652000 |
| 4| 123.9 | 1427652900 |

并获取每天的最大日期行,例如(开始日和结束日之间)-我需要了解如何至少按天对其进行分组,但如果有任何方法可以通过自定义期间(周、月)进行分组会很棒

SELECT id, param, MAX(date) FROM table WHERE date BETWEEN 1427652000 AND 1427824799
SELECT id, param, MAX(date) FROM table  WHERE date BETWEEN 1427824800 AND 1427911199

但实际上我获得了近一年的更多数据和 1000 多行数据,并且我认为 365 次查询不是一个选项,但我不知道如何优化它

UPD 毕竟我认为得到一个查询来得到这样的结果是真实的:

|id| param | date       |
|==|=======|============|
| 2| 122.3 | 1427825800 |
| 4| 123.9 | 1427652900 |

【问题讨论】:

  • 你试过GROUP BY吗?另外,请编辑您的问题,以举例说明您期望的结果。
  • 想要的输出是什么样的?
  • @rlanvin ,真的我不明白如何分组,是否可以通过“之间”进行分组?怎么样?
  • 好的,看起来你需要这个:stackoverflow.com/questions/8154170/…
  • @rlanvin tnx 我之前检查过,然后再试一次,例如 SELECT id, param, max(date) FROM table GROUP BY if(date between 1427652000 and 1427911199, 0, 1) 并且没有这样的功能 If对于 sqlite 有“案例”尝试像 SELECT id, weight, max(date) FROM weight GROUP BY case WHEN date 在 1427652000 和 1427911199 之间然后 0 else 1 没有运气我做错了什么?

标签: mysql sql sqlite


【解决方案1】:

这就是你想要的。您将使用GROUP BY 并使用DATE() 函数从每个项目中提取日期。 UNIX_TIMESTAMP()FROM_UNIXTIME() 有助于在 TIMESTAMPDATETIME 表示之间来回切换。这是必要的,因为日期算术的东西适用于DATETIME 值。 CURDATE() 表示今天。

SELECT DATE(FROM_UNIXTIME(`date`)) AS day,
       MAX(`date`) AS latest_timestamp_in_day
  FROM table
 WHERE `date` >= UNIX_TIMESTAMP(CURDATE() - INTERVAL 366 DAY)
   AND `date` < UNIX_TIMESTAMP(CURDATE())
 GROUP BY DATE(FROM_UNIXTIME(`date`))
 ORDER BY DATE(FROM_UNIXTIME(`date`)) DESC

这是有效的,因为

DATE(FROM_UNIXTIME(`date`))

获取每个时间戳并返回其所在日历日第一时刻的DATETIME 值。

第一个WHERE 子句选取一年零一天前或之后的日期。第二个不包括今天的日期;大概在尚未完成的那一天,MAX 操作没有多大意义。

从您的问题中不清楚您是否还希望显示与每个日历日的最后一个时间戳关联的 param 值。如果你这样做,那就有点难了。您首先需要获取每天最新的时间戳,然后您需要提取明细记录。这需要一个连接操作。您会将上述查询视为子查询,并将其加入您的table。像这样。

SELECT summary.day, detail.`date`, detail.param
  FROM table AS detail
  JOIN (
          SELECT DATE(FROM_UNIXTIME(`date`)) AS day,
                 MAX(`date`) AS latest_timestamp_in_day
            FROM table
           WHERE `date` >= UNIX_TIMESTAMP(CURDATE() - INTERVAL 366 DAY)
             AND `date` < UNIX_TIMESTAMP(CURDATE())
           GROUP BY DATE(FROM_UNIXTIME(`date`))
       ) AS summary ON detail.`date` = summary.latest_timestamp_in_day
 ORDER BY summary.day DESC 

不过要小心。 DATETIME 算术在本地时区完成。这可能会在当地时间从夏令时更改为标准时间并返回时导致奇怪的结果。

请注意,名为date 的列是反引号。它与 MySQL 查询语言中的保留字相同,因此反引号有助于消除歧义。

这里更详细地介绍了按日期分组的业务。 http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

【讨论】:

  • tnx 获取详细答案,尝试使用 sqlite SELECT DATE(date(date,'unixepoch')) AS day, MAX(date) AS latest_timestamp_in_day FROM table WHERE date >= date('now', '-366 days') AND date date)) ORDER BY DATE(date(date)) DESC 但我想我丢了东西
  • 需要一些时间来玩
  • 玩弄你的解决方案并解决它谢谢我需要阅读更多关于组和方法的信息
【解决方案2】:

您可以使用generator 生成每一天,然后加入您的表格:

SELECT r0 as start_day, MAX(date) 
(
 SELECT @row as r0, @row := @row + (24*60*60) as r1 FROM 
  (select 0 union all select 1 union all select 3 union all 
   select 4 union all select 5 union all select 6 union all 
   select 6 union all select 7 union all select 8 union all select 9) st1,
  (select 0 union all select 1 union all select 3 union all 
   select 4 union all select 5 union all select 6 union all 
   select 6 union all select 7 union all select 8 union all select 9) st2,
  (select 0 union all select 1 union all select 3 union all select 4 ) st3,
  (SELECT @row:=1420070400) st00  
) S
left outer join T
  on T.date BETWEEN S.r0 AND S.r1
where r1 <= 1451520000

【讨论】:

  • tnx - 我得到了这个解决方案,但它没有经过优化并且确实会产生太多查询 - 这就是我在这里的原因
  • date 上创建索引并检查千行表的性能。 sequence generator is already tested 和我的查询是索引友好的,没有行级函数。请不要跟我谈优化。
猜你喜欢
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
相关资源
最近更新 更多