【问题标题】:mySql INNER JOIN, MAX & DISTINCTmySql INNER JOIN, MAX & DISTINCT
【发布时间】:2014-09-24 10:41:59
【问题描述】:

我希望为每个“学生”类型的用户返回一行,显示他们的“姓名”和最新的“分数”(按时间倒序排列)。

我有两个表用户和服务

用户表

id  name    type
---|-------|-----
1  | Bob   | student 
2  | Dave  | student
3  | Larry | student
4  | Kevin | master

服务表

id   score   userId  date
---|--------|-------|------------
1  | 14     | 1     | 2014-09-04
2  | 99     | 3     | 2014-09-03
3  | 53     | 2     | 2014-09-07
4  | 21     | 1     | 2014-09-08
5  | 79     | 2     | 2014-09-08
6  | 43     | 3     | 2014-09-10
7  | 72     | 3     | 2014-09-10
8  | 66     | 2     | 2014-09-01
9  | 43     | 3     | 2014-08-22
10 | 26     | 1     | 2014-08-22

想要的结果

id   scores   name   date
---|--------|-------|------------
3  | 43     | Larry | 2014-09-10
1  | 21     | Bob   | 2014-09-08
2  | 79     | Dave  | 2014-09-08

我试过的是:

SELECT users.id, users.name, services.date, services.score
FROM users 
JOIN services ON users.id = services.userId
WHERE users.type='student'
ORDER BY services.date DESC

但这总是返回表中每个用户的最后日期。

所以我决定尝试像这样从另一端解决它:

SELECT servicesTemp.date, servicesTemp.score
FROM services servicesTemp
INNER JOIN
    (SELECT userId, MAX(date) AS MaxExpDate
    FROM services
    GROUP BY clientId) servicesTempGrp 
ON servicesTemp.userId = servicesTempGrp.userId 
AND servicesTemp.MaxDate = servicesTempGrp.MaxDate

但意识到如果日期相同,我最终会得到重复,并且我只能为每个用户返回一行(并且双重分组不起作用)。

我想我现在已经把这个复杂化了,所以非常感谢生命线。

【问题讨论】:

  • 你如何在 43 和 72 之间选择拉里的分数?
  • 在这种情况下并不重要,只要返回一个即可。
  • @TraceyTurn : 是的……因为你的datescores 不同步……你只是any score要退货吗?
  • 是的任何分数,只要它是该用户最近日期的分数。

标签: mysql sql join distinct


【解决方案1】:

尝试:

SELECT users.id, users.name, services.date, services.score
FROM users 
JOIN services ON users.id = services.userId
WHERE users.type='client'
AND services.date = (SELECT MAX(date) from services where userID = users.id)
ORDER BY services.date DESC

【讨论】:

    【解决方案2】:

    您可以使用substring_index()/group_concat() 技巧保证一行:

    SELECT u.id, u.name, max(s.date) as date,
           substring_index(group_concat(s.score order by date desc), ',', 1) as score
    FROM users u JOIN
         services s
         ON u.id = s.userId
    WHERE u.type = 'client'
    GROUP BY u.id, u.name
    ORDER BY s.date DESC;
    

    在不使用group by 的情况下,每个用户只获取一行的另一种选择是使用变量。或者,如果您知道 ID 是按顺序分配的,请使用 id 而不是 date

    SELECT u.id, u.name, s.date, s.score
    FROM users u INNER JOIN
         services s
         on u.userId = s.userId INNER JOIN
         (SELECT userId, MAX(id) AS MaxId
          FROM services
          GROUP BY userId
         ) smax
         ON s.userId = smax.userId and s.Id = smax.MaxId
    WHERE u.type = 'client';
    

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多