2017-06-05 189 views
1

我刚刚从'HackerRank'中遇到过这个问题。 BST表包含两列,分别为NPN代表节点,P代表家长:Oracle中的树层次结构

N P 
-- -- 
1 2 
3 2 
6 8 
9 8 
2 5 
8 5 
5 null 

样本输出应该是:

1 leaf 
2 inner 
3 leaf 
5 root 
6 leaf 
8 inner 
9 leaf 

我曾尝试是:

select  N, 
      case 
       when level = 3 then 'leaf' 
       when level = 2 then 'inner' 
       else 'root' 
      end 
from  BST 
start with P is NULL 
connect by P = prior N 
order by N; 

虽然给出正确的结果,我对代码的硬编码不太满意(不管它应该是叶,内部还是根)。此外,如果树中存在多个层次结构,此代码将失败。

有人可以建议任何其他优雅的方式来编写相同的代码,以便它不会失败的多层次?

+0

嗨!如果有人知道任何好的SQL挑战网站,请让我知道 – joe

回答

4

您可以使用connect_by_isleaf pseudocolumn的,而事实上,根永远有1级:

select  n, 
      case 
       when connect_by_isleaf = 1 then 'leaf' 
       when level = 1 then 'root' 
       else 'inner' 
      end 
from  bst 
start with p is null 
connect by p = prior n 
order by n; 
+0

嗨trincot!感谢你的回答 。您能否让我知道一些可以练习复杂的Oracle查询的好网站 – joe

+0

您可以创建一个免费的Oracle帐户,然后在https://livesql.oracle.com/上练习。然后还有http://rextester.com,虽然它似乎在同一个模式中运行所有脚本,所以经常会被破坏。 http://sqlfiddle.com也存在问题(Oracle数据库几乎从不运行)。但为何不在本地下载和安装Oracle数据库。 – trincot

+0

嗨Trincot!我的系统中安装了本地Oracle数据库。让我重述一下我的问题。您能否让我知道一些可以练习sql挑战/问题的好网站? – joe

3

Oracle提供a pseudocolumn CONNECT_BY_ISLEAF to test的青叶。对根的测试与START WITH子句相同。其他任何东西都是内在的。因此,这应该做你

select N , 
    case 
     when CONNECT_BY_ISLEAF = 1 then 'leaf' 
     WHEN P is NULL then 'root' 
     else 'inner' 
    end 
from BST 
start with P is NULL 
connect by P = prior N 
order by N; 
+0

@ MT0 - 谢谢。在我的第一杯咖啡之前,不应该回答问题:) – APC

+0

嗨,我是新来的stackoverflow。我已经获得了聊天的特权。你可以让我知道我该怎么和某人聊天? – joe

+0

嗨APC!感谢你的回答 。你可以让我知道一些好的网站,我可以练习复杂的Oracle查询 – joe

0

请用户像下面(对于MS SQL层次)

;以多层次(childID的,代,的ParentId) AS ( 选择ID,0 AS代,的ParentId FROM TABLE_NAME AS FirtGeneration WHERE的ParentId IS NULL
UNION ALL SELECT NextGeneration.Id,Parent.Generation + 1,Parent.ChildId FROM TABLE_NAME AS下一代 INNER JOIN海尔Archy AS Parent ON NextGeneration.ParentId = Parent.ChildId

SELECT * FROM Hierarchy ORDER BY Generation;

+0

这个问题被标记为'[oracle]'。而'[sql]'标签用于一般的SQL问题,而不是MS SQL Server – APC