Может кто-нибудь, пожалуйста, объяснить это решение узлов бинарного дерева хакерского ранга?

#mysql #sql

#mysql #sql

Вопрос:

 SELECT N, CASE WHEN P IS NULL THEN 'Root' 
WHEN(SELECT COUNT(*) FROM BST WHERE P = b.N) > 0 THEN 'Inner'
ELSE 'Leaf'
END
FROM bst b 
ORDER BY N;`
 

Может кто-нибудь, пожалуйста, объяснить это решение узлов бинарного дерева хакерского ранга? Почему есть p=b.n и почему это не работает, когда я использую from bst and p=bst.n вместо from bst b and p=b.n ?

Комментарии:

1. поскольку вы установили псевдоним, для bst которого b вы должны использовать so b для этого имени таблицы

Ответ №1:

Лучший способ написать этот код — определить все ссылки на столбцы. Поэтому я бы рекомендовал:

 SELECT b.N,
       (CASE WHEN b.P IS NULL
             THEN 'Root' 
             WHEN (SELECT COUNT(*) FROM BST b2 WHERE b2.P = b.N) > 0 
             THEN 'Inner'
             ELSE 'Leaf'
        END)
FROM bst b 
ORDER BY N;
 

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

Каковы условия? Логически, это:

 CASE WHEN <there is no parent>
     WHEN <at least one node has this node as a parent>
     ELSE <not a parent and no nodes have this as a parent>
END
 

Обратите внимание, что я настоятельно не рекомендую использовать COUNT(*) in коррелированный подзапрос, чтобы определить, есть ли совпадение. Гораздо лучше — как с точки зрения производительности, так и с точки зрения четкости — использовать EXISTS :

 SELECT b.N,
       (CASE WHEN b.P IS NULL
             THEN 'Root' 
             WHEN EXISTS (SELECT 1 FROM BST b2 WHERE b2.P = b.N) 
             THEN 'Inner'
             ELSE 'Leaf'
        END)
FROM bst b 
ORDER BY N;
 

Ответ №2:

Для получения значения столбца корневого узла P равно нулю. Для получения внутренних столбцов значением столбца P будут те, которые не равны нулю, но они могут появляться несколько раз, поэтому a отличается от значений столбцов, чтобы получить их и, наконец, rest все узлы тогда будут конечным узлом.

 SELECT N, 
CASE 
   WHEN P IS NULL 
       THEN 'Root' 
   WHEN N IN (SELECT DISTINCT(P) FROM BST WHERE P IS NOT NULL) 
       THEN 'Inner' 
   ELSE 'Leaf' 
END 
FROM BST 
ORDER BY N;
 

Комментарии:

1. Пожалуйста, добавьте некоторые пояснения к вашему ответу, чтобы другие могли извлечь из него уроки

2.Для получения значения столбца корневого узла P равно нулю. Для получения внутренних столбцов значением столбца P будут те, которые не равны нулю, но они могут появляться несколько раз, поэтому a отличается от значений столбцов, чтобы получить их и, наконец, rest все узлы тогда будут конечным узлом.

3. Пожалуйста, добавьте все пояснения к своему ответу, отредактировав его

Ответ №3:

На hackerrank вы можете попробовать именно это, если это поможет :

 select n,
case 
when p is null then 'Root'
when n in (select distinct(p) from bst) then 'Inner'
else 'Leaf'
end
from bst
order by n;
 

Ответ №4:

У вас есть два запроса bst . Основной и вложенный запрос с COUNT .

Вспомогательный запрос ссылается на свой собственный результат и на один из основных запросов ( b.N ) в его WHERE части.

Удаляя b псевдоним, вы также удаляете возможность ссылаться на основной запрос из подзапроса. И p=bst.n равно p=n , потому bst что относится к bst подзапросу, а не к основному запросу.

Комментарии:

1. зачем мне нужен псевдоним для ссылки на основной запрос из подзапроса?

2. @SaifAlSohad поскольку оба запроса запрашивают bst so, как следует SELECT COUNT(*) FROM BST WHERE P = N знать, что P это собственный запрос, но N относится к его основному запросу, оба P и N являются столбцами bst , поэтому N в этом случае также ссылаются на столбцы подзапроса.

Ответ №5:

SQL oracle:-

 select n,(case when P is null then 'Root'
when N not in(select nvl(p,0) from bst) then 'Leaf'
else 'Inner' end) from bst order by n;