2012-05-08 17 views
3

我有一个数据表,其中包含技术上是树结构的数据,但树是由代码和此代码的长度定义的。基于SQL中的代码计算树级别

的商品代码表包括的代码和描述:

例如:

Code Description 
------ ------------- 
0101 Live Animals 
01011 Horses 
010110 Purebred 
010190 Other 

项目的级别是由在其下方计数码计算。它下面的代码必须包含在当前代码中。如果那有意义的话。

所以在上面的例子:

0101 is level 0 (nothing is contained in it) 
01011 is level 1 (0101 is contained in it) 
010110 is level 2 (0101 and 01011 is contained in it) 
010190 is level 1 (only 0101 is contained in it) 

有没有办法让SQL这些水平?我正在使用DB2。

编辑: 尼古拉和戈登的解决方案都工作得很好,虽然我认为尼古拉的速度稍快!感谢你们!

不得不做出一些修改,以考虑DB2:

select 
    t1.code, count(t2.code) 
from commoditycode t1 
left join commoditycode t2 
on substr(t1.code, 1, length(t1.code) - 1) like concat(t2.code, '%') 
group by t1.code 
+1

哪个DBMS? PostgreSQL的?甲骨文? DB2? –

+0

你可以调整数据的存储方式么?这不是一个选项吗? – Purplegoldfish

+0

不幸的是我无法重组数据。我目前正在通过计算Java中的级别来解决这个问题。这是相当快速和高效的,但想知道是否有可能在纯SQL中执行此操作。 – Neil

回答

4

联接到本身代码减去最后一个字符会发现所有的父母在右侧。计数他们将得到的项目级别:

declare @test table (code varchar(10), name varchar(100)) 

insert into @test values ('0101', 'Live Animals') 
insert into @test values ('01011', 'Horses') 
insert into @test values ('010110', 'Purebred') 
insert into @test values ('010190', 'Other') 

select t1.code, t1.name, count (t2.code) + 1 [level] 
    from @test t1 
    left join @test t2 
    on substring (t1.code, 1, len (t1.code) - 1) like t2.code + '%' 
group by t1.code, t1.name 


code name   level 
01011 Horses   2 
0101 Live Animals 1 
010190 Other   2 
010110 Purebred  3 
+0

谢谢!非常聪明的解决方案,它运作良好。 删除了+1,因为0101是第0级。 – Neil

4

有趣的问题。如果我理解正确,这可以使用标准SQL解决。

这是想法。对于每个代码,我想将其与所有其他代码进行比较。我只关心其他代码,其中第一个代码的开头与整个其他代码相匹配。

一旦我有这个,我算了算这样的码数:

select code, description, count(*) as level 
from 
(
    select c.code, c.description, c2.code as abovecode 
    from commmodity c 
    left outer join commodity c2 on 
    on left(c.code, len(c2.code)) = c2.code 
    and c.code <> c2.code 
    group by c.code, c2.code 
) c 
group by code, description