2011-08-08 6 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. 각 레벨에서 사용자의 점수 합계를 기준으로 정렬.
  2. 사용자가 동일한 레벨에서 2 점을 얻은 경우 최신 점수 만받습니다.
    -------------------- 
    username | tpoint| 
    -------------------- 
        name_d | 8 | 
        name_b | 5 | 
        name_a | 3 | 
    -------------------- 
    

    name_ename_c

    이 무시되었습니다 : 사용자 이름으로
  3. 그룹은
  4. 총 점수는 레벨 당 점수의 10
  5. 최대 5

출력 샘플입니다해야합니다.

답변

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 

이 작업을 수행해야합니다. 그냥 "테이블"을 교체하십시오.

편집 :

당신이 5 이상 점수를 얻었다 행을 제외 또는 5와 같은 값을 하시겠습니까? 단지 WHERE 점을 제거하면 < = 5가됩니다.

+0

나는이 하나가 가까이 생각하지만, 당신은 규칙 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

확인, 첫 번째 부분이 ....

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은, 아주 잘 푸시 조건에 대처 따라서 최대-CONCAT 트릭,하지만 그 쿼리가 매우 복잡하게 만들려고하지 않습니다 복용 - 성능 문제가 있다면 다시 방문 할 가치가 있습니다. 이제 다른 것들에 추가 할 수 있습니다 .... 당신이 (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 
관련 문제