2011-11-28 36 views
0

我有一個(傳統)表中有列:SQL自聯接的多個屬性

bug_num build_id closed_to 
1   3   NULL 
2   4   NULL 
3   NULL   1 
4   3   NULL 
5   NULL   2 

我想編寫一個查詢它從一個特定的構建選擇所有的錯誤,所有的bug被關閉到該構建中的錯誤。所以,如果我想爲build 3做它,它會包含#1和4(因爲它們在build 3中),還有3,因爲它被關閉到build 3(1)中的一個bug。

我以爲我親近:

SELECT stat.bug_num, 
     stat.build_id 
FROM bug_status stat 
     JOIN bug_status stat2 
     ON stat2.closed_to = stat.bug_num 
WHERE stat.build_id = 3; 

...但它似乎並沒有被給我想要的結果。謝謝你的幫助!

+0

要澄清,「關閉」不是構建ID,它是一個錯誤號。 – pennstatephil

回答

2
SELECT stat.bug_num, 
     stat.build_id 
    FROM bug_status stat 
WHERE stat.build_id = 3 
    OR stat.closed_to IN 
     (SELECT stat2.bug_num 
      FROM bug_status stat2 
      WHERE stat2.build_id = 3 
     ) 
; 

(也有可能與JOIN要做到這一點,或與JOIN和UNION,但我相信上面是最直觀的方式。)


編輯補充:這裏是一個MySQL轉錄物證實以上:

mysql> create table bug_status 
    -> (bug_num numeric, build_id numeric, closed_to numeric); 
Query OK, 0 rows affected (0.01 sec) 

mysql> insert into bug_status values (1, 3, null); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into bug_status values (2, 4, null); 
Query OK, 1 row affected (0.01 sec) 

mysql> insert into bug_status values (3, null, 1); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into bug_status values (4, 3, null); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into bug_status values (5, null, 2); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT stat.bug_num, 
    ->  stat.build_id 
    -> FROM bug_status stat 
    -> WHERE stat.build_id = 3 
    ->  OR stat.closed_to IN 
    ->   (SELECT stat2.bug_num 
    ->    FROM bug_status stat2 
    ->   WHERE stat2.build_id = 3 
    ->  ) 
    -> ; 
+---------+----------+ 
| bug_num | build_id | 
+---------+----------+ 
|  1 |  3 | 
|  3 |  NULL | 
|  4 |  3 | 
+---------+----------+ 
3 rows in set (0.00 sec) 

編輯補充,因爲IN (...)的做法似乎並沒有在OP的版本的MySQL的工作:下面是給出了同樣結果的替代查詢:

SELECT stat.bug_num, 
     stat.build_id 
    FROM bug_status stat 
    LEFT 
OUTER 
    JOIN bug_status stat2 
    ON stat.closed_to = stat2.bug_num 
WHERE stat.build_id = 3 
    OR stat2.build_id = 3 
; 
+0

不幸的是,構建ID是當一個錯誤關閉到另一個錯誤時被清除,因爲它不知道什麼時候會實際執行另一個錯誤,所以我需要將closed_to直接映射到bug_num ... – pennstatephil

+0

重新讀取,它看起來像您的解決方案可能工作,但對於一些因爲sql似乎不喜歡嵌套查詢。 – pennstatephil

+0

@pennstatephil:很奇怪。我剛剛在MySQL版本5.1.53上測試了我的查詢,並返回了正確的行。你有可能錯誤地複製了一些東西嗎? – ruakh

2

您還沒有包括stat2.build_id您的WHERE子句(我認爲從錯誤的表中取得您的ON列):

SELECT stat.bug_num, stat.build_id 
FROM bug_status stat 
LEFT JOIN bug_status stat2 
ON stat.closed_to = stat2.bug_num 
WHERE stat.build_id = 3 OR stat2.build_id = 3 
+0

很奇怪......如果我完全刪除了where子句,它會給出一堆帶有bug ID 0和build ID爲null的行。似乎連接沒有妥善把表連接在一起? – pennstatephil

+0

這是不對的。它有幾個問題;例如,'stat2.build_id = 3'永遠不會是真的,因爲每當'bug_status.closed_to IS NOT NULL'時(至少在問題中的示例數據中)都是'bug_status.build_id IS NULL'。 – ruakh

+1

試試'ON stat.closed_to = stat2。bug_num' – knittl

0

爲什麼不:

DECLARE @build_id int = <the build id> 

SELECT stat.bug_num, stat.build_id, stat.closed_to 
FROM  bug_status stat 
WHERE stat.build_id = @build_id 
    OR stat.closed_to = @build_id 

+0

SQL上的+1,但語法看起來像TSQL而不是MySQL。你可能最好刪除聲明並在你的答案中輸入文字值,並讓OP找出如何處理參數 –

+3

'closed_to'映射到'bug_num'而不是'build_id' – knittl

0

此查詢...

SELECT * 
FROM bug_status t1 
WHERE 
    build_id = 3 
    OR EXISTS (
     SELECT * 
     FROM bug_status t2 
     WHERE 
      t2.build_id = 3 
      AND t1.closed_to = t2.bug_num 
    ) 

...產生以下結果:

bug_num build_id closed_to 
1   3   NULL 
3   NULL  1 
4   3   NULL 

用簡單的英語:選擇行這樣的:

  • build_id = 3
  • 或者存在與build_id = 3相關的行。