简体   繁体   中英

MySQL Return Distinct rows based on highest value of column

So I have 2 tables in MySQL (MariaDB). One has all unique data per row, the other has the version history of the first tables unique data. There is only one key between the 2, GeoID.

The table (t1) with unique ID and GeoID

ID , GeoID , ColumnA , ColumnB

This table (t2) has the version history.

ID , VersionID , GeoID , TerrainID , Action

So I am doing a LEFT JOIN on t2 where the GeoID matches in both tables and action = 4. The catch is, because t2 is a version table, it can return multiple rows where the GeoID matches, showing all versions. I need the latest version of the data from t2 joined with t1, and from t1 I only want rows from ColumnA that are 0

Lets have some values of

     t1
     ID | GeoID | ColumnA | ColumnB
     1  |  1000 |    0    |  42
     2  |  4387 |    3    |  432
     3  |  9573 |    0    |  NULL

     t2
     ID | VersionID | GeoID | TerrainID | Action
     1  |     1     |  1000 |    221    |   4
     2  |     2     |  1000 |    313    |   2
     3  |     1     |  4387 |    541    |   4
     4  |     1     |  9573 |    329    |   4
     5  |     3     |  1000 |    323    |   4
     6  |     2     |  9573 |    423    |   1

Now, what I need returned are the rows are the JOINed values on GeoID, the associated TerrainID from t2 and only the values from t2 where the version is the MAX for that geoid row.

So it should look like this, table above column denotes where the data comes from.

       t1        t2        t2
     GeoID | TerrainID | Version
      1000 |    323    |   3
      9573 |    423    |   2

Doing the LEFT OUTER JOIN against a GROUPed version of the t2 table should do the trick:

SELECT t1.GeoID, t2_grouped.VersionID, t2_grouped.TerrainID
FROM t1
LEFT OUTER JOIN (SELECT GeoID, TerrainID, MAX(VersionID) AS VersionID FROM t2 GROUP BY GeoID, TerrainID) t2_grouped
  ON t2_grouped.GeoId = t1.GeoID

WHERE t1.ColumnA = 0

Please try:

SELECT
   t1.GeoID,
   t2_lastver.TerrainID,
   t2_lastver.VersionID,
   t2_lastver.Action
FROM
   t1
   LEFT OUTER JOIN
   (
      SELECT
         t2.*
      FROM
         t2
      WHERE
         t2.ID in (SELECT MAX(t2_max.ID) FROM t2 AS t2_max WHERE t2_max.GeoID = t2.GeoID)
   ) AS t2_lastver
      ON t2_lastver.GeoID = t1.GeoID
WHERE 
   t1.ColumnA = 0;

Here you can find an SQL Fiddle illustrating the query.

Hope it helps.

Try this:

SELECT 
    t1.GeoID,
    t2.TerrainID,
    t.Version
FROM t1
LEFT JOIN (
    SELECT
        GeoID,
        Version = MAX(VersionID)
    FROM t2
    WHERE Action = 4
    GROUP BY GeoID
) AS t 
    ON t.GeoID = t1.GeoID
LEFT JOIN t2
    ON t2.GeoID = t.GeoID
    AND t2.VersionId = t.Version
WHERE
    t1.ColumnA = 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM