2011-01-29 7 views
1

私は、次の列からなるテーブルを持っています。現在、決定子カウント

child_count | path 
------------+----- 
      |/
      | /a 
      | /a/a 
      | /a/b 
      | /a/b/c 
      | /b 

、唯一のパス列にはデータがあります。私は次のように各パスの子数を決定することができるであろうSQL(好ましくはPostgreSQLの)クエリを知っているしたいと思います:

child_count | path 
------------+----- 
2   |/
2   | /a 
0   | /a/a 
1   | /a/b 
0   | /a/b/c 
0   | /b 

答えて

1

Andomarが私を打つが、それはいくつかを使用するように私はとにかく私の解決策を投稿しますPostgreSQL固有のもの。オフトピックしかし、好奇心のうち

 
with path_elements as (
    select path, array_length(string_to_array(path, '/'),1) as element_count 
    from path_table 
) 
select parent_path, count(child_path) 
from (
    select p.path as parent_path, 
     c.path as child_path 
    from path_elements p 
    left join path_elements c 
       on p.element_count + 1 = c.element_count 
      and substring(c.path, 1, length(p.path)) = p.path 
) t 
group by parent_path 
order by parent_path; 
+0

私は答えとしてこれをPostgreSQLのように選択しました。 – user593996

1

あなたがして、パスの深さを数えることができる:

len(path) - len(replace(path,'/','')) 

その後、子供たちは両親より1つの多いの深さを持って、そして子供たちのパスが親パスで始まる:

on  children.depth = parents.depth + 1 
     and substring(children.path, 1, len(parents.path)) = parents.path 

SQL Server用に(一緒にこれを置くが、マイナーCHAでのPostgresで動作するはずですNGES):

;with depth as 
     (
select depth = case when path = '/' then 0 
        else len(path) - len(replace(path,'/','')) 
       end 
,  path 
from YourTable 
     ) 
select COUNT(children.path) as child_count 
,  parents.path 
from depth parents 
left join 
     depth children 
on  children.depth = parents.depth + 1 
     and substring(children.path, 1, len(parents.path)) = parents.path 
group by  
     parents.path 

この版画:

child_count path     
----------- -------------------- 
2   /     
2   /a     
0   /a/a     
1   /a/b     
0   /a/b/c    
0   /b     

テストデータ:私が編集している間に

if OBJECT_ID('YourTable') is not null 
    drop table YourTable 
create table YourTable (child_count int, path varchar(max)) 
insert YourTable (path) values 
('/'), 
('/a'), 
('/a/a'), 
('/a/b'), 
('/a/b/c'), 
('/b') 
+0

私はそう頻繁にこれを見るために:なぜSQL ServerでのCTEは常に**接頭辞**セミコロンで?セミコロンは通常、ステートメントを終了させますか?ステートメントの開始時にセミコロンが表示されるのは、常にSQL Serverのソリューションです(そして、これまでの説明は必要ありません)。 –

+0

@a_horse_with_no_name:SQL Serverでは、オプションで、セミコロン。しかし、 'with'ステートメントの前の行には必須です。省略すると、間違った方向に向かうエラーメッセージが表示されます。このような状況を避けるために、ほとんどの人は 'with 'の前にセミコロンを付けるという習慣を採用しています。興味深いことに、説明のおかげで – Andomar

+0

。私はSQLでCTEの前にセミコロンを使用したことがなく、エラーも発生しませんでした。そして、私はいつも私のステートメントを終了するためにセミコロンを使います。しかし、私は私のSQLを実行するために、Microsoftのツールを使用していません... –

関連する問題