【问题标题】:group by highest point and shortest time按最高点和最短时间分组
【发布时间】:2013-10-10 06:24:26
【问题描述】:

我想查询最高点的排名,如果点相同,检查完成时间最短。我的桌子是

 +-------------------------------------------------+
 | | id | user_id | point | finishtime  | week  | |
 +-------------------------------------------------+
 | | 1  | G1      | 1560  |    55       |    1  | |
 | | 2  | G1      | 1560  |    43       |    1  | |
 | | 3  | G1      | 1530  |    55       |    1  | |
 | | 4  | G2      | 1760  |    45       |    1  | |
 | | 5  | G3      | 1760  |    46       |    1  | |
 | | 6  | G3      | 1330  |    25       |    2  | |
 | | 7  | G4      | 360   |    65       |    1  | |
 | | 8  | G2      | 1760  |    50       |    1  | |

预期结果是

 +-------------------------------------------------+
 | | id | user_id | point | finishtime  | week  | |
 +-------------------------------------------------+
 | | 4  | G2      | 1760  |    45       |    1  | |
 | | 5  | G3      | 1760  |    46       |    1  | |
 | | 2  | G1      | 1560  |    43       |    1  | |
 | | 7  | G4      | 360   |    65       |    1  | |
 | | 6  | G3      | 1330  |    25       |    2  | |

我尝试为该点选择最大值,但它不会花费最短的完成时间。

我需要按唯一 user_id 的结果组,按最高点和最短完成时间获取顺序。

我需要使用 if else 语句吗?

【问题讨论】:

  • (删除了一个答案) - 为什么你只保留两行 point=1760 ? IE。标准是什么?
  • 有些人可以得到相同的分数,当分数相同时,我们看到第二个标准是最短时间。谁获得的时间最短,谁的排名高。可以是同一用户或不同用户

标签: mysql


【解决方案1】:

这是一个可能的答案:

SELECT t1.* FROM t t1
JOIN (
  SELECT t1.user_id, t1.week, t1.point, min(t1.finishtime) ft FROM t t1
  LEFT JOIN t t2
  ON t1.week = t2.week AND t1.user_id = t2.user_id AND t1.point < t2.point
  WHERE t2.point IS NULL
  GROUP BY t1.user_id, t1.week, t1.point
) t2 ON t1.user_id = t2.user_id AND t1.week = t2.week AND
        t1.point = t2.point AND t1.finishtime = t2.ft
ORDER BY t1.week, t1.point DESC, t1.finishtime

结果

| ID | USER_ID | POINT | FINISHTIME | WEEK |
|----|---------|-------|------------|------|
|  4 |      G2 |  1760 |         45 |    1 |
|  5 |      G3 |  1760 |         46 |    1 |
|  2 |      G1 |  1560 |         43 |    1 |
|  7 |      G4 |   360 |         65 |    1 |
|  6 |      G3 |  1330 |         25 |    2 |

小提琴here.

这基本上是一个双最大的每组问题,因为您需要首先获得最高分的分数,然后是最短完成时间的分数。

另一种解决方案是通过...进行双重分组,但这将涉及第三个嵌套级别并试图避免它,因此选择了左连接解决方​​案。

【讨论】:

  • 非常感谢您的回答,它有效!这是一个需要考虑的复杂逻辑。你真的很专业
  • 嗨,你介意解释一下,为什么你需要两个t1?我并没有真正了解您对 sql 语句的逻辑。感谢您的辛勤工作!
  • 您实际上并不需要 2 t1,您可以命名两个 t3 之一。如您所见,对 t1 的外部引用永远不会进入JOIN (x)。连接中的t1 引用仅在其中使用,这就是没有命名问题的原因。简短说明:将JOIN 中的所有t1 引用替换为t3,它应该以相同的方式工作。
【解决方案2】:

这是一种只使用JOINS的方法

 SELECT
    DISTINCT
    t1.user_id,
    max(t2.point),
    min(t2.finishtime),
    min(t1.week)
 FROM
    t t1
    JOIN t t2 ON ( t1.user_id = t2.user_id )
 GROUP BY 
    t1.user_id
 HAVING
    MAX( t1.point ) = MAX( t2.point )
    AND MIN( t1.finishtime ) = MIN( t2.finishtime )
 ORDER BY 
    t1.user_id

结果:

| USER_ID | MAX(T2.POINT) | MIN(T2.FINISHTIME) | MIN(T1.WEEK) |
|---------|---------------|--------------------|--------------|
|      G1 |          1560 |                 43 |            1 |
|      G2 |          1760 |                 45 |            1 |
|      G3 |          1760 |                 25 |            1 |
|      G4 |           360 |                 65 |            1 |

感谢莫斯蒂的SQLFIDDLE

【讨论】:

  • 你的答案不是我所期望的。我想先比较点,然后再跟记录时间的同一行。我已经把结果放在那里了。
【解决方案3】:
SELECT id, user_id, point, finishtime, week
FROM (  SELECT id, user_id, point, finishtime, week
        FROM table_name
        ORDER BY point DESC, finishtime ASC) AS h
GROUP BY user_id, week
ORDER BY week ASC

这可能是使用未记录行为的最短方法之一。阅读下文。

【讨论】:

  • 你的 sql 输出没有获得最高分和最低分。时间。但是这两个记录都可以在原始差异下。我需要的是它必须是同一行。
  • 立即尝试。我可能第一次想错了。
猜你喜欢
  • 1970-01-01
  • 2015-01-13
  • 2012-09-26
  • 1970-01-01
  • 2014-09-15
  • 2017-10-15
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
相关资源
最近更新 更多