哦,MySQL,您如何按日期加入相关记录

哦,MySQL,您如何按日期加入相关记录,mysql,Mysql,我有一个看似简单的问题,很可能是一个简单的解决方案;然而,这一简单的解决方案让我不知所措。我在StackOverflow的浩瀚网络中搜索和跋涉,只找到了一些看似极其复杂的解决方案。我已经解决了这个问题,但是,这太恶心了,我为此感到羞耻。当然还有更好的方法,因为一定有一个身穿闪亮盔甲、挥舞着查询剑的骑士,他能想出一个简单而优雅的解决方案。下面是: 为了回答这个问题,我们将使这两个表保持简单 Table 1 users (user_id, active, name) 及 在这种情况下,将根据需要添

我有一个看似简单的问题,很可能是一个简单的解决方案;然而,这一简单的解决方案让我不知所措。我在StackOverflow的浩瀚网络中搜索和跋涉,只找到了一些看似极其复杂的解决方案。我已经解决了这个问题,但是,这太恶心了,我为此感到羞耻。当然还有更好的方法,因为一定有一个身穿闪亮盔甲、挥舞着查询剑的骑士,他能想出一个简单而优雅的解决方案。下面是:

为了回答这个问题,我们将使这两个表保持简单

Table 1
users (user_id, active, name)

在这种情况下,将根据需要添加用户的记录。然后,在用户完成项目时添加相关记录

我的问题是:使用查询,如何获得一条记录,其中包含表1中的所有信息,活动用户与表2中的记录关联,记录的最新日期基于开始日期

换句话说,如果我有这个:

| user_id | active | name  |
| 1       | 1      | brian |
这是:

| user_project_id | user_id | start_date | details |
| 1               | 1       | 2013-10-02 | proj 1  |
| 2               | 1       | 2013-11-26 | proj 2  |
| 3               | 1       | 2014-01-02 | proj 3  |
生成提供以下信息的查询:

| user_id | active | name  | user_project_id | user_id | start_date | details |
| 1       | 1      | brian | 3               | 1       | 2014-01-02 | proj 3  |

哦,请哦,请给我一个答案,没有答案我肯定会枯萎。

您可以使用top 1并按日期订购

select top 1 a.user_id,a.name,b.user_project_id,b.user_id,b.start_date,b.details
from users a join users_project b on a.user_id = b.user_id
order by b.start_date desc
对不起,我没有注意到OP问题中的mysql标记。您可以使用Limit关键字

 select  a.user_id,a.name,b.user_project_id,b.user_id,b.start_date,b.details
from users a join users_project b on a.user_id = b.user_id
order by b.start_date desc Limit 1

因为在MySQL中没有像
top
选择器这样的东西,所以可以使用triple
JOIN
,比如:

SELECT
  user_projects.*,
  users.*
FROM
  (SELECT 
    MAX(start_date) AS max_date, 
    user_id
  FROM
    user_projects
  GROUP BY
    user_id) AS max_dates
  LEFT JOIN
    user_projects 
      ON max_dates.max_date=user_projects.start_date
      AND max_dates.user_id=user_projects.user_id
  LEFT JOIN
    users
      ON users_projects.user_id=users.user_id

首先选择每个用户最新的项目:

SELECT a.*
FROM user_projects a
JOIN (
  SELECT user_id, MAX(start_date) AS max_start_date
  FROM user_projects
  GROUP BY user_id
) b ON a.user_id = b.user_id AND a.start_date = b.max_start_date
它从
user\u projects
创建一个小助手表,其中包括用户以及每一行的最新项目日期;要获得所有相应的表字段,必须再次将其与
user\u项目
连接起来

然后,您只需将上述结果加入
用户
,即可获得最终结果:

SELECT *
FROM users
JOIN (
  SELECT a.*
  FROM user_projects a
  JOIN (
    SELECT user_id, MAX(start_date) AS max_start_date
    FROM user_projects
    GROUP BY user_id
  ) b ON a.user_id = b.user_id AND a.start_date = b.max_start_date
) c ON users.user_id = c.user_id

MySQL中没有
top
选择器只是为了明确起见:您想为每个用户及其最近的项目指定一行吗?仅供参考,您正试图找到“分组最大值”。(将来应该可以帮你用谷歌搜索)。用一个查询就可以做到这一点(如下所示),但效率可能非常低-不要害怕用代码进行某些处理。@aidan,是的。分组最大值;我以前没听过这个词。谢谢你。这是正确的答案,没有我看到的那么复杂,也远没有我看到的那么复杂。它也是最精确和通用的。非常感谢。左连接似乎是多余的。@Jack,此查询确实产生了所需的输出,但是,我想知道是否可以进一步改进。注意:如果用户有两个(或更多)项目具有相同的
start\u日期
,您将在结果集中看到重复的用户。另外,没有项目的用户将不会出现在结果集中
SELECT a.*
FROM user_projects a
JOIN (
  SELECT user_id, MAX(start_date) AS max_start_date
  FROM user_projects
  GROUP BY user_id
) b ON a.user_id = b.user_id AND a.start_date = b.max_start_date
SELECT *
FROM users
JOIN (
  SELECT a.*
  FROM user_projects a
  JOIN (
    SELECT user_id, MAX(start_date) AS max_start_date
    FROM user_projects
    GROUP BY user_id
  ) b ON a.user_id = b.user_id AND a.start_date = b.max_start_date
) c ON users.user_id = c.user_id