2

プロットとデータ検査に使用する大規模なデータベースがあります。簡単にするために、次のようになるとします。

|    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    | 
                ...

これは、1 日に多くのポイントが測定される株式市場のデータである可能性があります。

私がやりたいことは、1 日あたりの複数のポイントが不必要に解決され、プロット アプリケーションを詰まらせる、はるかに長いトレンドを調べることです。(私は30000日を見たいと思っています。それぞれに約100の観測があります)。

のようなことをする方法はありますかSELECT ... LIMIT 1 PER "day"

正しい ID を見つけるためにいくつかのSELECT DISTINCTクエリを実行できると思いますが、組み込みの場合は単純なことをしたいと思います。

1 日あたりの最初、最後、または平均値であるかどうかは問題ではありません。単一の値です。私はただ最速のものを好みます。

また、Postgres、MySQL、および SQLite に対してもこれを行いたいと考えています。私のアプリケーションは 3 つすべてを使用するように構築されており、頻繁に切り替えています。

ありがとう!

背景: これは Ruby on Rails プロット アプリケーション用なので、ActiveRecord を使用したトリックも機能します。https://github.com/ZachDischner/Rails-Plotter

4

2 に答える 2

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(day=@day, @r:=@r+1, @r:=0) AS RN, @day:=day AS d, *
  FROM stockmarketdata
) AS t
WHERE t.RN = 1
于 2013-02-15T16:39:26.187 に答える
1

あなたの声明には、多くのオプションの余地が残されています。

1 日あたりの最初、最後、または平均値であるかどうかは問題ではありません。単一の値です。私はただ最速のものを好みます。

そのため、id を除外し、最初に各グループの obs の平均を使用することを提案します。これは、最も単純でおそらく最も実用的ですが、統計関数と制限を実行するのが最速ではない可能性があります。

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

最小限が必要な場合:

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

最大にしたい場合:

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

(注: 次の 2 つの例は、単に SQL を入力するよりも効率的ではありませんが、より移植性がある可能性があります。)

ただし、次の 3 つすべてが必要な場合があります。

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)

中央値が必要な場合 は、DB固有のこの質問を参照してください。検索すると、関連する他の投稿があります。

さらに、postgres のような一部の DBvariance(...)には 、stddev(...)などが組み込まれています。

最後に、クエリの作成に関する詳細については、Rails ガイドのクエリ セクションとARelを確認してください。たとえば、firstまたはを介し​​て ActiveRecord リレーションで制限を行うことができ、ARel で制限を行うことができます。この質問への回答に示されているように、サブクエリも可能であり、group by なども同様です。あなた自身の他のデータベースとそれを維持します。limittake

于 2013-02-15T17:46:04.880 に答える