Получить последних детей из базы данных

Моя ситуация:

Table A
(
ID
Parent_Id
TimeStamp
)

Корень имеет Parent_Id null, а дочерний элемент имеет идентификатор своего отца.

Я просто хочу получить всех ПОСЛЕДНИХ детей каждой таблицы А. Отец и дети мне не нужны. (кроме последнего).

Можно ли построить SQL, чтобы получить это?

PS: я использую sql где угодно 11. Может быть, ansi sql может решить эту проблему, я не уверен.

РЕДАКТИРОВАТЬ: (отредактировано для предоставления дополнительных сведений) Мне не нужны последние дочерние элементы элемента.

Пример:

Идентификатор 1 Родитель NULL

Идентификатор 2 Родитель 1

Идентификатор 3 (последний ребенок) Родитель 1

Идентификатор 4 Родительский NULL

Идентификатор 5 (последний ребенок) родитель 4

Я хочу получить: Id 3 Id 5


person Ismael    schedule 20.11.2009    source источник
comment
Пожалуйста, просмотрите свой ответ, потому что я дал дополнительную информацию.   -  person Ismael    schedule 20.11.2009


Ответы (4)


Использование сохраненной функции

create function LastChild(in parent integer)
returns integer
begin
    declare res integer;  
    select top 1 id into res from TableA where parent_id = parent order by timeCol desc;
    return res;
end

Выбрать

select Id, lastchild(id) from TAbleA where parent_id is null

Я буду работать над другим решением без хранимой функции.

РЕДАКТИРОВАТЬ: без сохраненной функции:

select Id, (select top 1 id from TableA childs where parent_id = TableA.id order by timeCol desc) from TableA where parent_id = 0
person Zote    schedule 20.11.2009
comment
Да! эта функция вернула именно то, что я хотел. Спасибо. - person Ismael; 20.11.2009
comment
Еще раз спасибо, версия sql без функции мне больше подошла. - person Ismael; 20.11.2009

Если под «последними дочерними элементами» вы подразумеваете элементы, которые сами по себе не имеют дочерних элементов (и часто упоминаются как конечные элементы), должно выполняться что-то вроде этого:

SELECT ID
 from A
 where ID not in (select Parent_Id from A)

Коррелированную версию подзапроса немного сложнее понять, но она будет работать быстрее на больших таблицах:

SELECT ID
 from A OuterReference
 where not exists (select 1 from A where Parenti_ID = OuterReference.ID)

(«OuterReference» — это псевдоним для таблицы A)

Я использую SQL Server, но это довольно простой синтаксис, и он должен работать для вас с минимальными изменениями.

person Philip Kelley    schedule 20.11.2009
comment
(Спустя годы, упс) настройте первый подзапрос так, чтобы он читался (select Parent_Id from A where Parent_Id is not null). Элементы верхнего уровня будут иметь нулевой ParentId, а наличие нулей в списке подзапроса приведет к путанице. - person Philip Kelley; 26.02.2014

select * from a where id not in (select parent_id from table a)

Другими словами, выберите все из таблицы a, где идентификатор элемента не является родительским идентификатором любого другого элемента. Это даст вам все листовые узлы графа.

РЕДАКТИРОВАТЬ:
Ваше редактирование немного сбивает с толку, и идентификаторы обычно не используются в качестве механизмов упорядочения, но независимо от этого приведенный вами пример может быть выполнен с помощью этого запроса.

SELECT MAX( id )
FROM a
WHERE id NOT IN
  (SELECT parent_id
      FROM a
      WHERE parent_id IS NOT NULL
  )
GROUP BY parent_id
person Jherico    schedule 20.11.2009

Мне пришлось немного обновить запрос, чтобы получить только дочерние категории для Postgres 9.4.

select count(id) from A as outer_ref where not exists(
    select 1 from A where parent_id=outer_ref.id) and parent_id is not null;
person Vasili Pascal    schedule 04.05.2021