Почему нет похожих идентификаторов в наборе результатов при запросе с коррелированным запросом внутри предложения where

У меня есть таблица с идентификаторами столбцов, именем, фамилией, созданной (датой).

У меня есть следующая таблица:

ID | Forename | Surname | Created
---------------------------------
 1 | Tom      | Smith   | 2008-01-01
 1 | Tom      | Windsor | 2008-02-01
 2 | Anne     | Thorn   | 2008-01-05
 2 | Anne     | Baker   | 2008-03-01
 3 | Bill     | Sykes   | 2008-01-20

Basically, I want this to return the most recent name for each ID, so it would return:

ID | Forename | Surname | Created
---------------------------------
 1 | Tom      | Windsor | 2008-02-01
 2 | Anne     | Baker   | 2008-03-01
 3 | Bill     | Sykes   | 2008-01-20

Я получаю желаемый результат с этим запросом.

SELECT id, forename, surname, created
FROM name n
WHERE created = (SELECT MAX(created)
                              FROM name
                              GROUP BY id
                              HAVING id = n.id);

Я получаю результат, который хочу, но не понимаю, ПОЧЕМУ ИДЕНТИФИКАТОРЫ НЕ ПОВТОРЯЮТСЯ в наборе результатов. Что я понимаю о коррелированном подзапросе, так это то, что он берет одну строку из внешней таблицы запросов и запускает внутренний подзапрос. Разве он не должен повторять «id», когда идентификаторы повторяются во внешнем запросе? Может кто-нибудь объяснить мне, что именно происходит за кулисами?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
0
38
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Во-первых, вашему подзапросу не нужен GROUP BY. Чаще пишут так:

SELECT n.id, n.forename, n.surname, n.created
FROM name n
WHERE n.created = (SELECT MAX(n2.created)
                   FROM name n2
                   WHERE n2.id = n.id
                  );

Вы должны выработать привычку уточнять ссылки на столбцы все, особенно если ваш запрос содержит несколько ссылок на таблицы.

Я думаю, вы спрашиваете, почему это работает. Ну, каждая строка во внешнем запросе проверяется на условие. Условие: "это мое created такое же, как максимальное created для всех строк в таблице name с одинаковым id". В ваших данных только одна строка на id соответствует этому условию, поэтому ids не повторяются.

Upwoting это, чтобы сделать заметку для себя. Это правильный способ выполнения таких задач.

user14063792468 23.07.2019 17:38

Вы также можете рассмотреть возможность объединения таблиц по значениям столбцов created vs max(created):

SELECT n.id, n.forename, n.surname, n.created
  FROM name n
  RIGHT JOIN ( SELECT id, MAX(created) as created FROM name GROUP BY id ) t
    ON n.created = t.created;

или с помощью оператора IN:

SELECT id, forename, surname, created
  FROM name n
 WHERE ( id, created ) IN (SELECT id, MAX(created)
                             FROM name
                            GROUP BY id );

или используя EXISTS с предложением HAVING в подзапросе:

SELECT id, forename, surname, created
  FROM name n
 WHERE EXISTS (SELECT id
                 FROM name
                GROUP BY id
                HAVING MAX(created) = n.created 
                );

Demo

Другие вопросы по теме