2011-05-18 87 views
0

抓取下令行下面是從表中的某些條目:SQL查詢:從表中

 
id  r_id  a_id  p_id

1 9 9 0 2 9 105 108 3 9 102 9 4 9 106 105 5 9 108 102

是否可以使用SQL查詢來獲取以下輸出

 
1  9   9   0 
3  9   102   9 
5  9   108   102 
2  9   105   108 
4  9   106   105 

的想法是以這樣的方式對行進行排序,使得具有p_id = x的行應該在a_id = x的行的下方。

我希望問題有道理。

問候,
Mayank

編輯:
我期待這對PostgreSQL

  • 根項目具有的p_id = 0
  • 沒有缺失環節

回答

1

使用遞歸查詢(PostgreSQL版本8.4或更高版本):

/* test data: 
CREATE TABLE foo (id, r_id, a_id, p_id) AS 
    SELECT 1,9,9,0 
    UNION ALL SELECT 2,9,105,108 
    UNION ALL SELECT 3,9,102,9 
    UNION ALL SELECT 4,9,106,105 
    UNION ALL SELECT 5,9,108,102   
; 
*/ 

-- the query you need: 
WITH RECURSIVE sub(s_id, s_r_id, s_a_id, s_p_id, row) AS (
    SELECT id, r_id, a_id, p_id, 1 AS row FROM foo WHERE p_id = 0 
UNION ALL 
    SELECT id, r_id, a_id, p_id, (row + 1) FROM foo JOIN sub ON s_a_id = p_id 
) 
SELECT * FROM sub ORDER BY row; 
+0

非常感謝。但是,只需要關於性能的建議。獲取所有值然後在內存中對其進行排序會有多好/更糟糕? – Mayank 2011-05-18 07:49:27

+0

使用EXPLAIN ANALYZE查看查詢的執行方式以及使用的內存量。根據您的情況,您可能需要對work_mem的設置進行一些更改。 – 2011-05-18 07:51:56

1

以下從適用的SQL Server 2005解決方案進行了改編。

我已經取得了一些假設

  • 根項目有p_id = 0
  • 沒有缺失的環節

SQL語句

;WITH RECURSIVE q AS (
    SELECT * 
      , 1 AS Level 
    FROM ATable 
    WHERE p_id = 0 
    UNION ALL 
    SELECT t.* 
      , Level = Level + 1 
    FROM q 
      INNER JOIN ATable t ON t.p_id = q.a_id   
) 
SELECT * 
FROM q 
ORDER BY 
     Level 
+0

OP編輯了這個問題,他正在尋找一個與postgreSQL數據庫兼容的答案。編輯前,我不會低調回答,但請考慮編輯您的答案。 – 2011-05-18 07:52:32

+1

@Johann - 我從來沒有看過postgreSQL,但看着接受的答案和我的,你幾乎沒有注意到任何差異(遞歸似乎是唯一的)。 OP應該能夠自己解決這個問題。 – 2011-05-18 08:01:13

+0

這兩個答案都可以接受。當我意識到如何使用postgresql完成時,我得到了另一個答案。現在,我只能接受一個答案:)。 – Mayank 2011-05-18 08:38:41