2011-08-08 27 views
4

これはテーブルであるこのクエリはどのように作成できますか?

---------------------------------------------- 
id | username | point | level | created_date 
---------------------------------------------- 
1 | name_a | 1 | 1 | 2011-08-01 
2 | name_a | 2 | 2 | 2011-08-02 
3 | name_b | 5 | 1 | 2011-08-02 
3 | name_c | 6 | 1 | 2011-08-02 
4 | name_d | 1 | 1 | 2011-08-01 
5 | name_d | 3 | 1 | 2011-08-02 
5 | name_d | 5 | 2 | 2011-08-03 
4 | name_e | 5 | 1 | 2011-08-01 
5 | name_e | 5 | 2 | 2011-08-02 
5 | name_e | 5 | 3 | 2011-08-03 
---------------------------------------------- 

を試験するためのクエリの要件は、(1つのクエリに可能な限り)テーブルのユーザ名、ポイントを照会することです。

  1. 各レベルでのユーザーのスコアの合計で並べ替えます。
  2. ユーザーが同じレベルで2点のスコアを取得した場合、最新スコアのみを取得します。
  3. グループ名で
  4. 合計スコアがレベルごとにスコアの10未満の
  5. 最大でなければならない5

出力サンプルです:

-------------------- 
username | tpoint| 
-------------------- 
    name_d | 8 | 
    name_b | 5 | 
    name_a | 3 | 
-------------------- 

name_ename_cが無視されました。

答えて

7

楽しい質問のようですね!

SELECT username, SUM(point) AS points 
FROM (SELECT username, level, point 
     FROM (SELECT username, level, LEAST(point, 5) AS point 
      FROM table 
      WHERE points <= 5 
      ORDER BY created_date DESC) AS h 
     GROUP BY username, level) AS h2 
GROUP BY username 
HAVING points < 10 
ORDER BY points DESC 

これがそれです!ちょうど "テーブル"を置き換えます。

EDIT:

は、あなたが5以上のスコアを得た行を除外したい、または5としての価値を持っていますか?その場合は、点を削除してください。< = 5。

+0

私はこの1つは近いと思いますが、あなたは、ルール2が隠されているスコア – Mfoo

+0

をチェックするCASE文を追加する必要がありますか? – duedl0r

+0

まず、created_dateがソートされたテーブルをフェッチします。次に、ユーザー名とレベルでGROUP BYを実行します。これにより、created_date DESCでソートされた最新の値がポイントに与えられます。 –

2
SELECT SUM(t3.point) AS tpoint, t3.username 
FROM (
    SELECT t1.level, t1.username, t1.created_date, t1.point 
    FROM testing AS t1 
    INNER JOIN (SELECT level, username, MAX(created_date) AS MaxDate 
       FROM testing) AS t2 
      ON (t1.level=t2.level AND t1.username=t2.username AND t1.created_date = t2.MaxDate) 
    WHERE t1.point <= 5 
    ) AS t3 
GROUP BY t3.username 
HAVING tpoint < 10 
ORDER BY tpoint DESC 

エイリアスを正しく使用しているかどうかわかりませんが、これがうまくいきましょう。

ジョインを使用した内部クエリでは、最新のユーザ名、レベルの組み合わせ(単一レベルのポイント数> 5)を取得します。これを使用して、ユーザ名の合計を取得し、10ポイントを超えるものを破棄します。

1

OK、最初の部分2を取る....

SELECT * 
FROM table a 
WHERE NOT EXISTS (
    SELECT 1 
    FROM table b 
    WHERE b.username=a.username 
    AND a.created_date>b.created_date 
) 

しかし、MySQLは、非常によくプッシュ述語で、したがって最大化連結トリックを対応しておりませんが、それは、クエリが非常に複雑になるだろうパフォーマンス上の問題がある場合は、再訪する価値があります。今、他のものに追加します....あなたは4は、この制約は他の制約(特に2及び5に関連して適用される正確な配列に依存して実装する方法部品1,3と

SELECT username, level, SUM(point) 
FROM 
(SELECT * 
    FROM table a 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM table b 
     WHERE b.username=a.username 
     AND a.created_date>b.created_date 
    ) 
) ilv 
GROUP BY username, level 
HAVING SUM(point) <= 5; 

5 )。あなたは、出力セットのレベル内訳を見て興味がないということだけで、再びこれを読んで、見て - -

SELECT username, level, SUM(point) 
FROM 
(SELECT * 
    FROM table a 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM table b 
     WHERE b.username=a.username 
     AND a.created_date>b.created_date 
    ) 
) ilv, 
(SELECT username, SUM(point) as totpoint 
    FROM table c 
    GROUP BY username 
    HAVING SUM(point)<=10) ilv2 
WHERE ilv.username=ilv2.username 
GROUP BY username, level 
HAVING SUM(point) <= 5; 

おっと...規定の入力からdisred出力を与える必要があり、以下、その場合のロビンの答えを中優れている。

2
SELECT 
    Query2.username 
    , Sum(Query2.SomVanpoint) AS point 
FROM 
    (SELECT 
      test.username 
      , test.level 
      , Sum(test.point) AS SomVanpoint 
     FROM 
      test 
     INNER 
     JOIN 
      (SELECT 
        test.username 
        , test.level 
        , Max(test.created_date) AS MaxVancreated_date 
       FROM 
        test 
       GROUP 
        BY test.username 
        , test.level 
      ) AS Query1 
      ON 
      (test.username   = Query1.username) 
      AND (test.level  = Query1.level) 
      AND (test.created_date = Query1.MaxVancreated_date) 
     GROUP 
      BY test.username 
      , test.level 
     HAVING 
      (((Sum(test.point))<= 5)) 
    ) AS Query2 
GROUP 
    BY Query2.username 
HAVING 
    (((Sum(Query2.SomVanpoint))< 10)) 
ORDER 
    BY Sum(Query2.SomVanpoint) DESC; 

===出力:

username | point 
----------+------ 
name_d | 8 
name_b | 5 
name_a | 3 
関連する問題