[英]MySQL - Left Join on MAX timestamp
我知道這是一個常見的問題,因為我之前曾問過,並且已經看過其他幾個問題了,但是盡管如此,盡管我提出了疑問,但還是無法解決。 請參見: 基於max(timestamp)的 MySQL連接和mysql LEFT連接以獲取右表的最大值
基本上,我有一個由不同項目組成的表格(“椅子”,“桌子”),每種類型都有針對特定椅子或桌子的帶有其ID的記錄。 然后,我有一個位置表,該表保留了曾經到過的所有位置,包括當前位置。 當前位置由MAX時間戳記。
我的查詢旨在獲取所有項目,並加入當前位置。 我已經按照別人說的去做,但對我卻沒有用。 任何幫助表示贊賞。
編輯:我沒有說它是如何失敗的:它獲取記錄並進行聯接,並且它返回最大時間戳,但是不返回與MAX(timestamp)記錄相對應的記錄信息。 因此,它給出了正確的時間戳,但下限等並非來自具有MAX時間戳的記錄。
謝謝!
查詢:
$q = "SELECT
'chairs' AS work_type,
chairs.id AS work_id,
chairs.title,
chairs.dimensions,
CurrentLocations.floor,
CurrentLocations.bin,
CurrentLocations.bay,
CurrentLocations.other
FROM chairs
LEFT JOIN (
SELECT
locations.id AS loc_id,
locations.work_type AS clwt,
locations.work_id AS clwi,
locations.floor,
locations.bin,
locations.bay,
locations.other,
MAX(locations.timestamp) AS latestLocation
FROM
locations
GROUP BY
locations.work_type, locations.work_id
) CurrentLocations
ON CurrentLocations.clwi = chairs.id AND CurrentLocations.clwt = 'chairs'
WHERE cur_loc LIKE '%19th Street%'
ORDER BY
FIELD(floor, 'Basement', '3rd Floor', '4th Floor', '5th Floor'),
bin,
bay,
other";
嘗試這個:
SELECT
'chairs' AS work_type, -- do you really need this in the result?
c.id AS work_id,
c.title,
c.dimensions,
l.floor,
l.bin,
l.bay,
l.other
FROM
chairs AS c
LEFT JOIN
( SELECT work_id,
MAX(timestamp) AS latestLocation
FROM locations
WHERE work_type = 'chairs'
GROUP BY work_id
) AS cl -- CurrentLocations
ON cl.work_id = c.id
LEFT JOIN
locations AS l
ON l.work_type = 'chairs'
AND l.work_id = cl.work_id
AND l.timestamp = cl.latestLocation
WHERE
c.cur_loc LIKE '%19th Street%'
ORDER BY
FIELD(l.floor, 'Basement', '3rd Floor', '4th Floor', '5th Floor'),
l.bin,
l.bay,
l.other ;
描述:
你要:
基本上,我有一個不同項目的表(
chairs
,tables
),每種類型都有記錄,這些記錄帶有針對特定椅子或桌子的ID。 然后,我有一個locations
表,該表保留了曾經使用過的所有位置,包括當前位置。 當前位置以最大timestamp
。我的查詢旨在獲取所有項目(椅子),並加入當前位置。
因此,對於每個項目(即chair
),您只需要最新的 location
。 對於表location
每個work_id
,都需要MAX(timestamp)
。 您可以使用GROUP BY
輕松找到它:
( SELECT work_id,
MAX(timestamp) AS latestLocation
FROM locations
GROUP BY work_type
, work_id
) AS cl
但是,您還想使用該表中的其他列,如果僅將它們添加到選擇列表中,則會顯示錯誤的結果。 (請注意,在大多數DBMS中,為了使用不在GROUP BY
列表中的列,您必須應用一個聚合函數,就像將MAX()
應用於timestamp
。MySQL允許這種行為,如果使用得當,可以具有一些好處。但是它尚未實現100%的故障保護,因此在某些情況下(例如這種情況)應用它可能會產生錯誤的結果。Postgres對此功能的實現要好得多,不會出現錯誤的結果。)
因此,您要做的就是使用上述GROUP BY
查詢作為派生表(將其命名為cl
或CurrentLocation
,隨便使用什么),然后使用GROUP BY
列表中的所有列和匯總的表將其CurrentLocation
到locations
表中( timestamp
):
JOIN
locations AS l
ON l.work_type = cl.work_type
AND l.work_id = cl.work_id
AND l.timestamp = cl.latestLocation
之后,您可以像往常一樣將它們加入chairs
桌。 由於您在原始查詢中有一個chairs LEFT JOIN locations
,因此我也將其保留在答案中。
另一個較小的修改是,由於您具有CurrentLocations.work_id = 'chairs'
,因此只需要locations
表中的那些行。 因此,首先進行分組然后拒絕所有不符合該條件的行是相當多余的。 首先應用條件,然后進行分組可能更有效。 最終的分組查詢和加入條件將相應修改。
還要注意, (work_type, work_id, timestamp)
上的索引將提高查詢的效率(將僅使用該索引來處理cl
子查詢,而JOIN locations
也將使用該索引來定位location表中所需的行)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.