Вернуть 1 результат за левое соединение - PullRequest
2 голосов
/ 20 сентября 2010

В настоящее время я выполняю левое соединение на двух столах.В первой таблице есть идентификатор и имя человека, во второй таблице есть идентификатор, идентификатор человека из таблицы 1, а затем отметка времени (рейса).

People                             Flights
id   |  name             id   |   person_id   | time
------------             ---------------------------
1       Dave              1         1          1284762115
2       Becky             2         1          1284787352
                          3         2          1284772629
                          4         2          1286432934
                          5         1          1283239480

Когда я выполняюоставив, присоединяюсь, я получаю список людей и их время полета, но мне бы хотелось, чтобы был только список людей с временем полета с самым высоким ID

, который я использовал

   SELECT p.id, p.name max(f.time) 
     FROM People p 
LEFT JOIN Flights f ON p.id = f.person_id
 GROUP BY p.id, p.name

Однако, это просто дает мне ПОЛНОЕ время полета, а не время последнего полета, загруженное в систему (т. Е. Самый высокий ID).

1 Dave  1284787352
2 Becky 1286432934

Итак, повторюсь, яхотел бы видеть имя человека, а также время полета последнего загруженного (с наибольшим ID) времени полета.

1 Dave  1283239480
2 Becky 1286432934

Ответы [ 2 ]

6 голосов
/ 20 сентября 2010

Использование:

SELECT p.id,
       p.name,
       f.time
  FROM PEOPLE p
  JOIN FLIGHTS f ON f.person_id = p.id
  JOIN (SELECT f.person_id,
               MAX(f.id) AS max_id
          FROM FLIGHTS f
      GROUP BY f.person_id) x ON x.person_id = f.person_id
                             AND x.max_id = f.id

Если вы используете базу данных, которая поддерживает аналитику:

SELECT p.id,
       p.name,
       x.time
  FROM PEOPLE p
  JOIN (SELECT f.person_id,
               f.time,
               ROW_NUMBER() OVER(PARTITION BY f.person_id
                                     ORDER BY f.id DESC) AS rk
          FROM FLIGHTS f) x ON x.person_id = p.id
                           AND x.rk = 1

Если вы хотите, чтобы люди, в том числе без рейсов:

   SELECT p.id,
          p.name,
          f.time
     FROM PEOPLE p
LEFT JOIN FLIGHTS f ON f.person_id = p.id
     JOIN (SELECT f.person_id,
                  MAX(f.id) AS max_id
             FROM FLIGHTS f
         GROUP BY f.person_id) x ON x.person_id = f.person_id
                                AND x.max_id = f.id

... и аналитическая версия:

   SELECT p.id,
          p.name,
          x.time
     FROM PEOPLE p
LEFT JOIN (SELECT f.person_id,
                  f.time,
                  ROW_NUMBER() OVER(PARTITION BY f.person_id
                                        ORDER BY f.id DESC) AS rk
             FROM FLIGHTS f) x ON x.person_id = p.id
                              AND x.rk = 1
1 голос
/ 20 сентября 2010

Я думаю, что вы ищете что-то вроде ниже. сгруппируйте по person_id и выберите максимальный идентификатор, затем используйте этот список для выбора из рейсов. Это моя первая мысль, что может быть более эффективный способ.

РЕДАКТИРОВАНИЕ:

SELECT p.id, p.name MAX(f.time)  
     FROM People p  
LEFT JOIN Flights f ON p.id = f.person_id 
WHERE f.id in(SELECT MAX(id) FROM flights GROUP BY person_id)
...