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 以提高效率。
给定两个表 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 以提高效率。