22


8

私はのようなUSERテーブルがあれば

クラスage -------------- 1 20 3 56 2 11 1 12 2 20

それから私は簡単に各クラスで最年少のユーザーを取得することができます

クラスごとにユーザーグループからクラス、min(age)を選択します。

同様に、minをmaxに置き換えることで、最も古いものを取得できます。 しかし、どのようにして各クラスの10番目に若い(または最も古い)*人を得ることができますか? ところで、私はMySql v.5.0を使っています。

乾杯、

6 Answer


18


SELECT a.class,
(
    SELECT b.age
    FROM users b
    WHERE b.class = a.class
    ORDER BY age
    LIMIT 1,1
) as age
FROM users a
GROUP BY a.class

各クラスで2番目に若いです。 あなたが10番目に若いのが欲しいなら、あなたは `LIMIT 9,1`をするでしょう、そしてもしあなたが10番目に古いのが欲しいなら、あなたは `ORDER BY age DESC 'をするでしょう。


8


ここで「N」は「N番目」のレコード「最も古い」を表します

SELECT *
FROM users k
WHERE N = (SELECT
             COUNT( DISTINCT age)
           FROM users u
           WHERE k.age >= u.age
               AND k.class = u.class
           GROUP BY u.class)

そしてそれは「N番目」のレコード「最も若い」を与える

SELECT *
FROM users k
WHERE N = (SELECT
             COUNT(DISTINCT age)
           FROM users u
           WHERE k.age <= u.age
               AND k.class = u.class
           GROUP BY u.class)


2


SQLに依存しない唯一の方法(サブクエリmysql <5がない場合でも)

u1.class = u2.classおよびu1.age> = u2.ageグループのユーザーu2に、u1.class、u1.ageでcount(*)を指定して、u1からu1.class、u1.age、count(*)を選択します。 = [数]

あなたはクラスごとに最も古い[番号]を取得します

u1.class = u2.classおよびu1.age <= u2.ageグループのユーザーu2に、u1.class、u1.ageでcount(*)を指定して、u1からu1.class、u1.age、count(*)を選択= [数]

あなたは1クラスあたりの最も若い数を取得します

2人の人が同じ年齢であると、両方が返されるのでうまくいかない可能性があります。 そのうちの1つだけを返したい場合は、一意のキーが必要になり、クエリはもっと​​複雑になります。


0


SQL Serverでは非常に簡単です。

_ _

select
  *
from(
   select
      *,
      row_number() over(order by age asc) as eldest
   from class order by age asc) a
where a.eldest = 10

_ _

そのパターンに従って、MySQLの場合、私はあなたがこれを見たいと思うでしょう:http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/


0


SELECT userid、class、age、(SELECT COUNT(1)FROMユーザーWHEREクラス= c.class AND age> u.age)AS oldcount FROMユーザーAS u WHERE oldercount = 9 GROUP BYクラス

または

SELECTユーザーID、クラス、年齢ユーザーASからWHERE(SELECT COUNT(1)FROMクラスからWHEREクラス= c.class AND年齢> u.age)= 9 GROUP BYクラス


0


その上にテーブルを結合する任意の答えは二乗法則を作成します…​

-  a b = a.class = b.class AND a.age> = b.age
-  平均で> =条件はクラスの半分に当てはまる

-  1クラス6人 - > 6 * 6/2 = 18

-  10人 - > 10 * 10/2 = 50

 - >非常に急速な成長

テーブルサイズが大きくなると、パフォーマンスは急激に低下します。 あなたが物事を小さく保ち、それらがあまり成長しないのなら、それは問題ですか? あなたの電話は…

代替案はより多くのコードを含みますが、直線的に成長します…​

  • まず、Class、Ageの順に並べられたIDENTITYフィールドを使用して、すべてのレコードを新しいテーブルに挿入します。

  • さて、各クラスについて、MIN(id)を見つけます。

  • さて、各クラスについて、is = MIN(id)8(9番目の年長者のための)のレコードを調べます。

最後の2つのステップを実行する方法はたくさんあります。 私は個人的に使用します…​

SELECT [USER_WITH_IDS] .id、[USER_WITH_IDS] .class、[USER_WITH_IDS] .age FROM [USER_WITH_IDS] WHERE [USER_WITH_IDS] .id =(SELECT MIN([最小] .ID)8 FROM [USER_WITH_IDS] AS [最小] WHERE [ min] .class = [USER_WITH_IDS] .class)

これが与えるものは…​

  • 新しいIDを作成するためのワンパス

  • 各クラスのMIN(id)を取得するための1回のパス

  • 必要なレコードを入手するための1回のパス

  • また、最適化ツールの性能に応じて、インデックス(クラス、次にID)を使用すると、最後の2つのパスを1つのパスにまとめることができます。

テーブルやクラスのサイズがいくら大きくなっても、2〜3回パスします。 二乗則ではなく線形