Как реализовать & # 8220; hasChildren & # 8221; Оператор SELECT в SQL?
Вопрос
Допустим, у меня есть следующая таблица:
ID | parentID | MoreStuff
1 | -1 | ...
2 | 1 | ...
3 | 1 | ...
4 | 2 | ...
5 | 1 | ...
Как я могу сгенерировать оператор SQL SELECT, чтобы узнать, есть ли у конкретной строки дочерние элементы? Другими словами, я хочу знать, есть ли у ID 1 дети, а в нашем случае - 3.
Я не уверен, как создать инструкцию SQL:
SELECT ID, hasChildren FROM myTable;
Что будет заменено для hasChildren в приведенном выше операторе SQL SELECT?
Решение
Нет версии группы:
SELECT MyTable.Id, CASE WHEN EXISTS
(SELECT TOP 1 1 --you can actually select anything you want here
FROM MyTable MyTableCheck
WHERE MyTableCheck.ParentId = MyTable.Id
) THEN 1 ELSE 0 END AS HasRows
FROM MyTable
Другие советы
Присоединитесь к таблице, чтобы узнать, есть ли у нее дети:
SELECT
parent.id as ID
, case when count(child.id) > 0 then 1 else 0 end as hasChildren
FROM myTable parent
LEFT JOIN myTable child
ON child.parentID = parent.ID
GROUP BY parent.id
Если вы знаете, что уже знаете родительский идентификатор, тогда запрос прост - просто выберите количество строк с этим родительским идентификатором.
SELECT count(*) FROM myTable where parentID = 1;
Есть очень правильные ответы на ваш вопрос, которые будут работать. Тем не менее, я хотел бы рассмотреть производительность такого запроса, если ваш набор данных очень большой.
Если вы собираетесь использовать Group By или Sub Query для получения данных, убедитесь, что столбцы ID и Parent имеют отдельные индексы.
Чтобы добиться еще большей производительности, вы должны добавить столбец с именем " haschildren " который может быть "бит" тип данных. Этот столбец должен быть обновлен из кода приложения, когда элементы вставлены или удалены. Это позволит вам выполнить намного более быстрый запрос:
SELECT * FROM table WHERE haschildren IS NOT NULL
Вышеприведенные решения хороши, но вы не должны добавлять столбец, как 'haschildren', если у вас действительно нет проблем с производительностью (см. сообщение от GateKiller). Такой столбец денормализует базу данных, то есть один и тот же фрагмент информации будет храниться в двух местах, что повышает вероятность того, что ваши данные станут противоречивыми. Вы должны будете поддерживать этот столбец всякий раз, когда вставляете нового потомка, удаляете существующего или обновляете родителя потомка.