简体   繁体   English

我该如何进行此查询?

[英]How can I make this query?

This is the table for testing 这是测试表

----------------------------------------------
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
----------------------------------------------

Requirement for the query is to query (as much as possible in one query) the username, point of the table. 查询的要求是查询(尽可能在一个查询中)用户名,表的点。

  1. Order by sum of user's score on each level. 按每个级别的用户得分总和排序。
  2. If user have 2 score on the same level, it will only get the latest score. 如果用户在同一级别上获得2分,则只能获得最新分数。
  3. Group by username 按用户名分组
  4. total score must be less than 10 总分必须小于10
  5. maximum of the score per level is 5 每个级别的得分最高为5

Output sample: 输出样本:

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

name_e and name_c was ignored. name_ename_c被忽略。

Sounds like a fun query! 听起来很有趣!

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

This should do it! 这应该做到! Just replace "table". 只需替换“表”。

EDIT: 编辑:

Do you want to exclude rows which got a score over 5, or have the value as 5? 是否要排除得分超过5或值为5的行? Just remove WHERE points <= 5 if such. 如果是这样,只需删除WHERE点<= 5。

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

Don't know if I used the aliases correctly, hope this works! 不知道我是否正确使用了别名,希望这有效!

The inner query with the join is to get the latest username,level combination where single level point count is > 5. This is then used to get the total sum per username and discard those with more then 10 points. 连接的内部查询是获取最新的用户名,单级点数> 5的级别组合。然后用于获取每个用户名的总和并丢弃超过10个点的用户。

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; 

=== output: ===输出:

username  | point
----------+------
name_d    |  8
name_b    |  5
name_a    |  3

OK, taking part 2 first.... 好的,先参加第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
)

But mysql doesn't cope with push-predicates very well, hence the max-concat trick, but that's going to make the query very complicated - worth revisiting if you've got performance problems. 但是mysql并不能很好地处理推送谓词,因此最大限度的技巧,但这将使查询变得非常复杂 - 如果你遇到性能问题,值得重新审视。 Now to add in the other stuff....parts 1,3 and 5 现在添加其他东西....部分1,3和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
GROUP BY username, level
HAVING SUM(point) <= 5;

How you implement 4 depends on the exact sequence in which this constraint is applied in relation to the other constraints (particularly 2 and 5). 如何实现4取决于此约束相对于其他约束(特别是2和5)应用的确切顺序。 The following should give the disred output from the stated input... 以下应该从所述输入中给出disred输出...

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;

Whoops - just read this again and saw that you're not interested to see a level breakdown in the output set - in which case Robin's answer is better. 哎呀 - 再看一遍,看到你对输出集中的级别细分不感兴趣 - 在这种情况下,罗宾的答案更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM