2013-04-09 5 views
5

私は、次の表を持っている:"SELECT"コマンドで各グループの最初の2つのレコードを選択する最良の方法は何ですか?例えば

id group data 
1 1 aaa 
2 1 aaa 
3 2 aaa 
4 2 aaa 
5 2 aaa 
6 3 aaa 
7 3 aaa 
8 3 aaa 

「SELECT」コマンドにより、各グループの最初の2つのレコードを選択するための最良の方法は何ですか? そうする良い方法がない場合は、どのようなルーチンあなたは(PHPで)?

を示唆してください(モデルアウトカム)

1 1 aaa 
2 1 aaa 
3 2 aaa 
4 2 aaa 
6 3 aaa 
7 3 aaa 

私はa.id> = bでクロス参加することを知っていました。 idはサブクエリで動作することができますが、私は数百万のレコードを持つテーブルに適用できる、よりスケーラブルなソリューションを探しています。おかげ

+0

それとも、この使用できますか? MySQL、SQL Server、...? –

+0

最後にLIMIT 2を選択したクエリで、2つのレコード –

+0

が好きな方は、MySQLを使用することをお勧めしますが、これは可能な方法を知りたいので、使い慣れたものを使用するだけです。 –

答えて

8
select a.* 
from Tablename a 
where 
(
    select count(*) 
    from Tablename as b 
    where a.group = b.group and a.id >= b.id 
) <= 2 
+0

これは、私の友人から、クロス結合に 'a.id <= b.id'を使って提案された解決策ですが、' count(*) 'の不確定部分がインデックスパワーで大きくなっているという大きなパフォーマンスの問題を予見しましたテーブルは大きく成長しています。私は正しい?私の表現はちょっと混乱しているかもしれません。 –

+0

それは良いですが、最初の2つのレコードを与えていないので、最後の2つのレコードを与えていますので、それを確認してください.. –

+1

@Deepanshuそれは単に 'a.id> = b.id'に変更することができますhttp: //www.sqlfiddle.com/#!2/1b596/3 –

-1

あなたは、フィルタを選択して、通常のようなクエリとため、その後

を注文MSSQL

SELECT TOP 2 * FROM foo; 
私は Sybaseのオラクルを思い出すことができるものから、

、可能ないくつかの他のRDBMSのはこの構文を使用します。

はい、私は申し訳ありませんが、あなたの質問を読み違え:

MySQLの のためにあなたは

SELECT * FROM foo LIMIT 2; 

更新を行います。私たちのいくつかは:)

を行ったように、それはあなたRDBMSあなたはを有するかまたは、IN を使用してでサブクエリを使用してクエリを構築することができかどうかなどを備えたをサポートしているかどうかに依存しているようですIN句。

MSSQLのために私はあなたのようなもの(ないテストコード)

SELECT id, data 
    FROM (
     SELECT id, data, Rank() over (Partition BY group ORDER BY id DESC) AS Rank 
     FROM table 
     ) rs WHERE Rank <= 2) 

を行うことができると思います。しかし、これはあなたのRDBMSに依存するので、私は同様の質問を見て、もう1つは最高の作品かを確認するように依頼しますあなたのケースのためにMSSQLはいくつかの事をサポートしていますはそうではありません。ここで

は、いくつかの例では、私はこのトリックを好き

Select top 10 records for each category

How to select the last two records for each topic_id in MySQL

+0

おそらく質問を誤って読んでしまいました。その場合、私はグループごとに2つのレコードが必要になります。 –

3

あり、それは、GROUP_CONCAT集約関数を利用して、FIND_IN_SET:それはインデックスを利用することができないよう

SELECT 
    Tablename.* 
FROM 
    Tablename INNER JOIN (
    SELECT `group`, GROUP_CONCAT(id ORDER BY id) ids 
    FROM Tablename 
    GROUP BY `group`) grp ON 
    Tablename.`group` = grp.`group` AND 
    FIND_IN_SET(Tablename.id, ids)<=2 
ORDER BY 
    Tablename.`group`, Tablename.id 

公演は、あまりにも良いことはできません。あなたは何を使用しているRDBMS

SELECT t1.id, t1.`group`, t1.data 
from 
    Tablename t1 INNER JOIN Tablename t2 
    ON t1.`group` = t2.`group` AND t1.id>=t2.id 
GROUP BY 
    t1.id, t1.`group`, t1.data 
HAVING 
    COUNT(*)<=2 
ORDER BY 
    t1.`group`, t1.id, t1.data 
+0

代替提案のためにupvoted –

関連する問題