簡體   English   中英

MySQL-在MAX時間戳記上左加入

[英]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 ;

描述:

你要:

基本上,我有一個不同項目的表( chairstables ),每種類型都有記錄,這些記錄帶有針對特定椅子或桌子的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查詢作為派生表(將其命名為clCurrentLocation ,隨便使用什么),然后使用GROUP BY列表中的所有列和匯總的表將其CurrentLocationlocations表中( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM