web-dev-qa-db-ja.com

Oracleの「CONNECTBYPRIOR」、および「ORDERSIBLINGSBY」に相当するSQLServer

私はこのOracleコードを持っています構造SQL Server 2008に変換しようとしています注:一般名、角かっこ「[]」で囲まれた列名、テーブル名を使用し、コードを読みやすくするためにいくつかの書式設定を行いました)

SELECT [col#1], [col#2], [col#3], ..., [col#n], [LEVEL] 
FROM (SELECT [col#1], [col#2], [col#3], ..., [col#n] 
      FROM [TABLE_1] 
      WHERE ... ) 
CONNECT BY PRIOR [col#1] = [col#2] 
START WITH [col#2] IS NULL 
ORDER SIBLINGS BY [col#3]

上記のコードに相当するSQLServerテンプレートは何ですか?

具体的には、[〜#〜] level [〜#〜]、および 'ORDERに苦労しています[〜#〜]兄弟[〜#〜]BY'Oracleコンストラクト。

注:上記の「コード」は、一連のOracleプロシージャからの最終出力です。基本的に、 'WHERE'句は動的に構築され、渡されるさまざまなパラメータに応じて変化します。 'CONNECT BY PRIOR'で始まるコードブロックはハードコードされています


参考:

SQLSERVERでのOracleのCONNECTBY PRIORのシミュレーション の記事が近づいていますが、「LEVEL」および「ORDERSIBLINGS」構造の処理方法については説明されていません。 ...そして私の心はねじれています!

SELECT name 
  FROM emp
  START WITH name = 'Joan'
  CONNECT BY PRIOR empid = mgrid

に等しい:

WITH n(empid, name) AS 
   (SELECT empid, name 
    FROM emp
    WHERE name = 'Joan'
        UNION ALL
    SELECT nplus1.empid, nplus1.name 
    FROM emp as nplus1, n
    WHERE n.empid = nplus1.mgrid)
SELECT name FROM n

作業する初期テンプレートがある場合は、SQLServerのストアドプロシージャを構築して正しいT-SQLステートメントを作成するのに大いに役立ちます。

支援をいただければ幸いです。

6
user1058946

LEVEL列のシミュレーション

レベル列は、再帰部分のカウンターをインクリメントすることで簡単にシミュレートできます。

WITH tree (empid, name, level) AS  (
  SELECT empid, name, 1 as level
  FROM emp
  WHERE name = 'Joan'

  UNION ALL

  SELECT child.empid, child.name, parent.level + 1
  FROM emp as child
    JOIN tree parent on parent.empid = child.mgrid
)
SELECT name 
FROM tree;

order siblings byのシミュレーション

order siblings byのシミュレーションはもう少し複雑です。親ごとの要素の順序を定義する列sort_orderがあると仮定すると(全体的な並べ替え順序ではなく、order siblingsは必要ないため)、全体的な並べ替えを提供する列を作成できます。注文:

WITH tree (empid, name, level, sort_path) AS  (
  SELECT empid, name, 1 as level, 
         cast('/' + right('000000' + CONVERT(varchar, sort_order), 6) as varchar(max))
  FROM emp
  WHERE name = 'Joan'

  UNION ALL

  SELECT child.empid, child.name, parent.level + 1, 
         parent.sort_path + '/' + right('000000' + CONVERT(varchar, child.sort_order), 6) 
  FROM emp as child
    JOIN tree parent on parent.empid = child.mgrid
)
SELECT * 
FROM tree
order by sort_path;

sort_pathの式は非常に複雑に見えます。これは、SQL Server(少なくとも使用しているバージョン)には、先行ゼロで数値をフォーマットする単純な関数がないためです。 Postgresでは整数配列を使用するのでvarcharへの変換は必要ありませんが、SQLServerでも機能しません。

12

ユーザー「a_horse_with_no_name」によって与えられたオプションは私のために働いた。コードを変更してメニュージェネレータクエリに適用したところ、初めて機能しました。コードは次のとおりです。

WITH tree(option_id,
       option_description,
      option_url,
      option_icon,
      option_level,
      sort_path)
     AS (
     SELECT ppo.option_id,
            ppo.option_description,
          ppo.option_url,
          ppo.option_icon,
          1 AS option_level,
          CAST('/' + RIGHT('00' + CONVERT(VARCHAR, ppo.option_index), 6) AS VARCHAR(MAX))
     FROM security.options_table_name ppo
     WHERE ppo.option_parent_id IS NULL
     UNION ALL
     SELECT co.option_id,
            co.option_description,
          co.option_url,
          co.option_icon,
          po.option_level + 1,
          po.sort_path + '/' + RIGHT('00' + CONVERT(VARCHAR, co.option_index), 6)
     FROM security.options_table_name co,
          tree AS po
     WHERE po.option_id = co.option_parent_id)
     SELECT *
     FROM tree
    ORDER BY sort_path;
0
wtave