2013-02-15 61 views
2

我有一个用于绘图和数据检查的大型数据库。为简单起见,假设它看起来是这样的:有没有办法在SQL中应用移动限制>

| id | day | obs | 
+----------+-----------+-----------+ 
| 1  | 500 | 4.5 | 
| 2  | 500 | 4.4 | 
| 3  | 500 | 4.7 | 
| 4  | 500 | 4.8 | 
| 5  | 600 | 5.1 | 
| 6  | 600 | 5.2 | 
       ... 

这可能是股市的数据,在这里我们有一个测量每天多点。

我想要做的是看更长的趋势,每天多点不必要地解决,并堵塞我的绘图应用程序。 (我想看看30000天,每个有大约100观察)。

有没有办法做这样的事情SELECT ... LIMIT 1 PER "day"

我想我可以执行一些SELECT DISTINCT查询,找到正确的ID,但我宁愿做一些简单的,如果它是内置的。

它如果它是每天的第一个,最后一个或平均值,则无关紧要。只是一个单一的价值。我只是喜欢什么是最快的。

此外,我想为Postgres,MySQL和SQLite做到这一点。我的应用程序是建立使用所有三个,我经常在它们之间切换。

谢谢!

背景:这是针对Ruby on Rails绘制应用程序的,因此ActiveRecord的一个技巧也可以工作。 https://github.com/ZachDischner/Rails-Plotter

+0

您是否只想为每一天选择一个值或每天的平均值? – 2013-02-15 16:37:14

+0

请参阅这里:[如何在SQL中选择每个组的第一/最小/最大行](http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row -per基团在-SQL /)。 – 2013-02-15 16:38:28

+0

我想我应该指定 - 但对我来说并不重要。长期趋势可能需要随机每日价值或平均值。平均可能只需要更多时间来执行查询 – 2013-02-15 16:44:21

回答

3

您需要用您正在使用的RDBMS品牌标记您的问题。对Rails开发者来说,他们经常使用MySQL,但是你的问题的答案取决于这个。

对于除MySQL的所有品牌,正确的和标准的解决方案是使用窗口功能

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY day) AS RN, * 
    FROM stockmarketdata 
) AS t 
WHERE t.RN = 1; 

对于MySQL,不支持窗口函数的是,你可以在一种模拟它们与会话变量的笨拙方式:

SELECT * FROM (SELECT @day:=0, @r:=0) AS _init, 
(
    SELECT IF([email protected], @r:[email protected]+1, @r:=0) AS RN, @day:=day AS d, * 
    FROM stockmarketdata 
) AS t 
WHERE t.RN = 1 
+0

这太棒了!我会保持打开一两天,看看是否有更多的答案弹出。但这正是我期待的! – 2013-02-15 17:06:09

1

你留下了很大的空间与您的语句选项:

无论它是每天的第一个,最后一个还是平均值都无关紧要。只是一个单一的价值。我只是喜欢什么是最快的。

因此,我要离开它的ID,并首先建议每个组的obs的平均值作为最简单,也许是最实用的,虽然也许不是运行stat功能最快的vs vs 。限制:

MyModel.group(:day).average(:obs) 

如果你想最小:

MyModel.group(:day).minimum(:obs) 

如果你想最大:

MyModel.group(:day).maximum(:obs) 

(注意:以下两个示例的效率低于仅输入SQL的效率,但可能更便于携带。)

但你可能要三个:

ActiveRecord::Base.connection.execute(MyModel.select('MIN(obs), AVG(obs), MAX(obs)').group(:day).to_sql).to_a 

或者仅仅是数据,而散列:

ActiveRecord::Base.connection.exec_query(MyModel.select('MIN(obs), AVG(obs), MAX(obs)').group(:day).to_sql) 

如果你想中间,看到this question哪个更DB具体的,还有其他有关posts关于它,如果你搜索。

而对于更多的一些DB的像postgres有variance(...),stddev(...)built-in

最后,请查看Rails指南中的query sectionARel以获取有关构造查询的更多信息。例如,您可以通过firstlimit在ActiveRecord关系中进行限制,例如,在ARel中,take可让您执行限制。子查询也是可能的,如this question的回答所示,以及group by等也是如此。如果您与其他人共享此项目,请尝试限制您正在使用的非可移植SQL的数量,除非您打算为其他人添加支持数据库,并保持这一点。

+0

感谢您的回答。这个想法也适用,但为了加快速度,我会验证另一个解决方案。我很感激! – 2013-02-19 16:56:55

+0

请记住,数据质量通常比速度更重要。例如,第一个或最后一个观测数据点可能会隐藏更高或更低的值。室外温度就是一个很好的例子。如果你只在下午进行测量,温度往往会高于清晨。如果您只需要进行一次测量,则可能需要使用RAND()/ RANDOM()等。 – 2013-02-19 18:38:08

+0

绝对如此。我同意并赞赏意见。我将尝试实现这两种方法,并看看有什么作用。以你的榜样为例,你是对的,临时工在一天中都会改变。但是,如果我正在考虑长期(50年)的变化趋势(相对而非绝对),那么如果我在早上或下午3点录制,则无关紧要。那就是我正在看的那种数据。感谢您的输入! – 2013-02-20 20:04:29

相关问题