1

たとえば、2つのテーブルがあります。

1番目:オブジェクトと親の列

object | parent 
-------+---------
object1| null       
object2| object1  
object3| null  

2番目にあるもの:オブジェクトと参照列

object | reference
-------+---------
object1| null       
object2| null       
object3| object1       

次のように順序付けするためにテーブルをクエリする必要があります。親が最初で、次に-子、親への参照を持つオブジェクト。

object1
object2
object3

1つのSQLクエリで実行することは可能ですか、それとも配列で手動で並べ替える必要がありますか?それは古典的な仕事のようです、おそらく解決策はすでにどこかに存在しますか?

4

4 に答える 4

1

これはあなたが探しているものですか?

CREATE TABLE oparen (object varchar(10), parent varchar(10));
CREATE TABLE oref (object varchar(10), ref varchar(10));
INSERT INTO oparen VALUES
    ('object1',null),('object2','object1'),
    ('object3',null),('object4','object2');
INSERT INTO oref VALUES
    ('object1',null),('object2',null),('object3','object1'),
    ('object5','object6'),('object6','object1'),('object7','object4');

WITH hier AS (
    SELECT parent AS obj, 1 AS rank FROM oparen
     WHERE parent IS NOT NULL
    UNION
    SELECT object, 2 FROM oparen
     WHERE parent IS NOT NULL
    UNION
    SELECT object, 3 FROM oref
     WHERE ref IS NOT NULL),
allobj AS (
    SELECT object AS obj FROM oparen
    UNION
    SELECT object FROM oref)
SELECT a.obj, coalesce(h.rank, 4) AS rank
  FROM allobj a LEFT JOIN hier h ON a.obj = h.obj
 ORDER BY coalesce(h.rank, 4), a.obj;

編集:以下の回答の改善された例の後、次のクエリでうまくいくはずです:

WITH parents AS (
    SELECT parent AS obj, 1 AS rank FROM oparen
     WHERE parent IS NOT NULL
    ),
family AS (
    SELECT * FROM parents
    UNION ALL
    SELECT object, 2 FROM oparen op
     WHERE parent IS NOT NULL
       AND NOT EXISTS (SELECT obj FROM parents WHERE obj = op.object)
    ),
hier AS (
    SELECT * FROM family
    UNION ALL
    SELECT object AS obj, coalesce(f.rank + 2, 5) AS rank
      FROM oref LEFT JOIN family f ON oref.ref = f.obj
     WHERE ref IS NOT NULL
    ),
allobj AS (
    SELECT object AS obj FROM oparen
    UNION
    SELECT object FROM oref)
SELECT a.obj, h.rank AS rank
  FROM allobj a LEFT JOIN hier h ON a.obj = h.obj
 ORDER BY h.rank, a.obj;

上部のテストベッドの作成は、新しい要件に従って更新されます。

于 2012-04-19T06:59:19.900 に答える
0

いいえ、機能しません:別のデータをチェックし、使用を簡略化して、orefテーブルの内容によってのみ:

INSERT INTO oref VALUES
('object1',null),('object2',null),('object3','object1'),
('object5','object6'),('object6','object1'),('object7','object4'), ('object4','object5');

WITH family AS (
    SELECT object AS obj, 1 AS rank FROM oref
     WHERE ref IS NULL
    ),
hier AS (
    SELECT * FROM family
    UNION ALL
    SELECT object AS obj, coalesce(f.rank + 2, 5) AS rank
      FROM oref LEFT JOIN family f ON oref.ref = f.obj
     WHERE ref IS NOT NULL
    ),
allobj AS (
    SELECT object AS obj FROM oref)
SELECT a.obj, h.rank AS rank
  FROM allobj a
  LEFT JOIN hier h ON a.obj = h.obj
 ORDER BY h.rank, a.obj;

ここで再帰クエリを使用する必要があると考えてください。ここに書いて投稿します。

于 2012-04-29T21:03:11.573 に答える
0

次のデータを挿入しました:

INSERT INTO oparen VALUES
    ('object1',null),('object2','object1'),('object3',null),('object4','object2');
INSERT INTO oref VALUES
    ('object1',null),('object2',null),('object3','object1'),('object5','object6'),('object6','object1');

順序が正しくなく、object2が2回リストされています。objのDISTINCTも順序を壊します。6、次に5に行く必要があります。

于 2012-04-20T06:04:33.677 に答える
0

次の再帰クエリが機能します。

WITH RECURSIVE tables(object, rank) AS (
    SELECT DISTINCT o.object, 1 AS rank FROM oref o
    WHERE o.ref IS NULL
    UNION
    SELECT o.object, t.rank + 1 AS rank
    FROM (SELECT DISTINCT o.object, o.ref FROM oref o
            WHERE ref IS NOT NULL) o, tables t
    WHERE o.ref = t.object AND rank <= t.rank
),
ordered AS (
    SELECT * FROM tables
)
SELECT * FROM tables 
WHERE tables.rank = (SELECT MAX(rank) FROM ordered WHERE ordered.object = tables.object)
ORDER BY rank;

コメント、質問、異議、提案はありますか?;)

于 2012-05-02T10:06:27.270 に答える