36

「グループ化された」レコードの最初と最後のレコードをフェッチしようとしています。
もっと正確に言えば、私はこのようなクエリを実行しています

SELECT MIN(low_price), MAX(high_price), open, close
FROM symbols
WHERE date BETWEEN(.. ..)
GROUP BY YEARWEEK(date)

しかし、グループの最初と最後のレコードを取得したいと思います。たくさんのリクエストをすることでそれを行うことができましたが、私はかなり大きなテーブルを持っています。

MySQLでこれを行う(可能であれば処理時間が短い)方法はありますか?

4

4 に答える 4

61

あなたが使いたいGROUP_CONCATSUBSTRING_INDEX

SUBSTRING_INDEX( GROUP_CONCAT(CAST(open AS CHAR) ORDER BY datetime), ',', 1 ) AS open
SUBSTRING_INDEX( GROUP_CONCAT(CAST(close AS CHAR) ORDER BY datetime DESC), ',', 1 ) AS close 

これにより、コストのかかるサブクエリが回避され、この特定の問題に対しては一般的に効率的であることがわかります。

両方の関数のマニュアルページをチェックして引数を理解するか、MySQLで時間枠変換を行う方法の例を含むこの記事にアクセスして詳細を確認してください。

于 2009-10-12T02:09:59.240 に答える
2

これを最初に試してください...:

Select YearWeek, Date, Min(Low_Price), Max(High_Price)
From
   (Select YEARWEEK(date) YearWeek, Date, LowPrice, High_Price
    From Symbols S
    Where Date BETWEEN(.. ..)
    GROUP BY YEARWEEK(date)) Z
Group By YearWeek, Date
于 2009-09-04T14:30:13.760 に答える
0

この特定の問題に対する優れた具体的な解決策は次のとおりです。http: //topwebguy.com/first-and-last-in-mysql-a-working-solution/MySQL でFIRSTとLASTを使用するのとほぼ同じくらい簡単です。

実際に解決策を提供するコードを含めますが、テキスト全体を調べることができます。

SELECT
word ,  

(SELECT a.ip_addr FROM article a
WHERE a.word = article.word
ORDER BY a.updated  LIMIT 1) AS first_ip,

(SELECT a.ip_addr FROM article a
WHERE a.word = article.word
ORDER BY a.updated DESC LIMIT 1) AS last_ip

FROM notfound GROUP BY word;
于 2010-04-17T07:43:02.180 に答える
-1

最小のlow_priceと最大のhigh_priceを持つレコードのIDが必要であると仮定すると、これら2つの列をクエリに追加できます。

SELECT 

(SELECT id ORDER BY low_price ASC LIMIT 1) low_price_id,
(SELECT id ORDER BY high_price DESC LIMIT 1) high_price_id,

MIN(low_price), MAX(high_price), open, close
FROM symbols
WHERE date BETWEEN(.. ..)
GROUP BY YEARWEEK(date)

効率が問題になる場合は、「year_week」の列を追加し、カバーするインデックスをいくつか追加して、クエリを2つに分割する必要があります。

'year_week'列は、YEARWEEK(date)の値に設定されたINTであり、'date'列が更新されるたびに更新されます。このようにして、クエリごとに再計算する必要がなく、インデックスを作成できます。

新しいカバーインデックスは次のようになります。順序は重要です。KEY yw_lp_id(year_week、low_price、id)、KEY yw_hp_id(year_week、high_price、id)

次に、これら2つのクエリを使用する必要があります

SELECT 
(SELECT id ORDER BY low_price ASC LIMIT 1) low_price_id,
MIN(low_price), open, close
FROM symbols
WHERE year_week BETWEEN(.. ..)
GROUP BY year_week

SELECT 
(SELECT id ORDER BY high_price DESC LIMIT 1) high_price_id,
MAX(high_price), open, close
FROM symbols
WHERE year_week BETWEEN(.. ..)
GROUP BY year_week

カバーインデックスは非常に便利です。詳細については、こちらをご覧ください。

于 2009-09-06T05:22:18.097 に答える