5

私は、40年以上にわたって何十万もの価格帯を持っています. 最後の 500 が最新のデータ ポイントであり、残りの 2500 が残りのデータのサンプルであり、均等に分散された合計 3000 のデータ ポイントのみを返すクエリを作成したいと考えています。

1回のクエリでこれを行うことは可能ですか? 大量のデータのサンプルだけを選択するにはどうすればよいですか? これは、他の 2500 個のデータ ポイントのサンプルを取得するという意味の小さな例です。

1
2
3    
4
5
6
7
8
9
10

そして、私は次のようなものを返したいです:

1
5
10

最後の 500 件のクエリは次のとおりです。

SELECT * FROM price ORDER BY time_for DESC LIMIT 500

他のデータ ポイントからサンプル データを取得する方法がわかりません。

4

2 に答える 2

5

これを試して:

(SELECT * FROM price ORDER BY time_for DESC LIMIT 500)
UNION ALL
(SELECT * FROM price WHERE time_for < (SELECT time_for FROM price ORDER BY time_for LIMIT 500, 1) ORDER BY rand() LIMIT 2500)
ORDER BY time_for

注:おそらく遅くなるでしょう。このテーブルの大きさはどれくらいですか?

これらすべての行からプライマリIDのみを取得し、絞り込んだ後、セカンダリクエリで元のIDに結合する方が速い場合があります。これは、テーブル全体ORDER BY rand() LIMITを並べ替える必要があるためです。テーブルが大きい場合、これには長い時間がかかり、多くのディスク容量が必要になる可能性があります。IDのみを取得すると、必要なディスク容量が削減されます。

于 2012-09-06T04:44:00.220 に答える
3

前の回答は良いですが、結果を均等に分散するように指定したので、この可能性も追加します。行に対してカウンターを反復することにより、MOD 演算子を使用して均等な分布をサンプリングできます。現在、これをテストするための MYSQL をインストールしていないため、構文が 100% 正しくない場合は申し訳ありません。しかし、それは十分に近いはずであり、いくつかのアイデアを与えるかもしれません.

  (  SELECT p1.*
       FROM price p1
   ORDER BY p1.time_for DESC
      LIMIT 500  )

   UNION ALL

  (  SELECT @i := @i + 1 AS row_num,
            p2.*
       FROM price p2,
            (SELECT @i: = 0)
      WHERE row_num > 500
        AND (row_num % 500) = 0
   ORDER BY time_for DESC  )

最初のクエリは、最新の 500 行を返します。2 番目のクエリでは、その後 500 行ごとに返されるため、残りのデータから均等な分布が返されます。明らかに、このパラメーターを調整して、目的のサンプル間隔を実現できます。または、テーブル内の行の総数に基づいて、正確に 2500 レコードを提供するために必要な間隔を計算します。

于 2012-09-10T13:59:28.870 に答える