MySQL 左加入最新记录

MySQL Left Join with latest record

给定两个表 A 和 B,我想要 A 中 A.Param = "X" 的所有记录。我还想要 B 上的 LEFT JOIN,其中 B 包含各种 A.Ids 的各种试验 m、n、o...

的试验记录

B 上的记录的时间戳为 B.TrialTime(DateTime)。随着设计的进行,B 中的相同 A.Id 可以对同一个实验进行多次试验,为了 LEFT JOIN 的目的,我只需要最新的试验。这是我想出的:

SELECT A.*, B.Experiment, B.Response, B.Evaluation, MAX(B.TrialTime) FROM A
LEFT JOIN B ON B.UserID = A.ID
WHERE A.Param = "X" GROUP BY concat(B.UserID, B.Experiment)

问题是,它不再充当 LEFT JOIN,即我没有从 A 获取所有用户,即使他们在 B 中没有任何记录,这正是我需要的。有帮助吗?

无法访问您的 table 的详细信息,您面临的问题是了解 "the most recent" 试用(在 table B 中)

在许多 rdbms 中,可以使用 ROW_NUMBER() 来解决这个问题,但到目前为止 MySQL 还没有提供那个有用的函数。所以你需要做这样的事情:

SELECT
        a.*
      , b.*
FROM A
        LEFT JOIN
        (
                SELECT
                        bb.*
                FROM B bb
                        INNER JOIN
                        (
                                SELECT
                                        UserID
                                      , MAX(TrialTime) MostRecent
                                FROM B
                                GROUP BY B.UserID
                        ) bmax ON bb.UserID = bmax.UserID
                                AND bb.TrialTime = bmax.MostRecent
        ) b ON B.UserID = A.ID

基本上不可能同时获取某些列的 MAX() 和所有其他列的值 "from that row"。您需要获取 MAX(TrialTime),然后返回相同的 table 以获得适当的行。

为了比较,如果 row_number() 可用,则可以这样做:

SELECT
        a.*
      , b.*
FROM A
        LEFT JOIN
        (
                SELECT
                        bb.*
                      , ROW_NUMBER() OVER (PARTITION BY bb.userid 
                                           ORDER BY bb.TrialTime DESC) AS rn
                FROM B bb
        ) b ON B.UserID = A.ID
                AND b.rn = 1

顺便说一句,没有给出任何使用 LEFT [OUTER] JOIN 的具体原因。如果您希望 A 中的行在 B 中没有联接数据,那么您将需要一个外部联接,否则您应该使用 INNER JOIN 以提高效率。