2012-08-16 90 views
1

SELECT查詢我有一個多表查詢,看起來像:SQL - 優先過濾

SELECT tree.name, tree.type, branch.name, branch.type, leaf.name, leaf.type 
FROM tree, branch, leaf 
WHERE leaf.branch_id = branch.id 
    AND branch.tree_id = tree.id 
ORDER by field(tree.type, 'Poplar', 'Birch', 'Hazelnut') 

所以這給了我屬於任何三種樹條目的所有葉項。

現在,我真的只想返回屬於一棵樹的葉子條目,按照指定的順序。

因此,如果有葉子條目屬於白楊樹,只顯示這些。但是,如果沒有Poplar Leaf條目,則只顯示屬於Birch樹的葉條目。

可能有任何數量的葉條目。我只想要那些出現在我的優先級列表中的樹。理想情況下只使用一個查詢。

任何想法?在此先感謝....

+1

請畫表結構必不可少的虛擬數據和http://sqlfiddle.com – diEcho 2012-08-16 10:32:57

回答

0

試試這個:

SELECT * FROM 
(
    SELECT tree.name, tree.type, branch.name, branch.type, leaf.name, leaf.type, 
      IF(@var_type = '' OR a.type = @var_type, a.type := @var_type, 0) AS check_flag 
    FROM tree, branch, leaf, (SELECT @var_type := '') 
    WHERE leaf.branch_id = branch.id 
      AND branch.tree_id = tree.id 
    ORDER by field(tree.type, 'Poplar', 'Birch', 'Hazelnut') 
) a 
WHERE check_flag <> 0; 
+1

所需輸出你能解釋一下嗎?請注意,這不是一個有效的MySQL查詢,說實話,我不知道它應該做什麼。 – adam 2012-08-16 11:29:03

0

我會建議使用http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set

有了,你可以做

SELECT * FROM (
    SELECT find_in_set(tree.type, "Poplar,Birch,Hazelnut") as sequence, tree.name, tree.type, branch.name, branch.type, leaf.name, leaf.type 
    FROM tree, branch, leaf 
    WHERE leaf.branch_id = branch.id 
     AND branch.tree_id = tree.id 
    ORDER by sequence 
    ) WHERE sequence = 1 
+0

儘管存在一些錯誤(我已經進行了適當的編輯),但我對這種方法有了相當的瞭解,但是序列= 1沒有考慮到缺少樹(僅選擇Poplar)....理想情況下我希望sequence = min (序列) - 你能進一步幫助嗎? – adam 2012-08-16 11:41:00

+0

@Adam我從閱讀文檔假設find_in_set(field,listSet)應該返回一個序列,而不是在listSet中的位置,但我可能錯了。你可能需要'HAVING sequence = min(sequence)'。 'ORDER BY'在這裏是無關緊要的,因爲無論如何你只選擇一個值。我目前無法訪問MySQL服務器來測試上述內容。 – 2012-08-16 12:07:08

0

下面是做到這一點的方法之一。該查詢首先爲每個葉子找到適當的樹型。然後,加入這一信息早在:

select tree.name, tree.type, branch.name, branch.type, leaf.name, leaf.type 
from (SELECT leaf.id, 
      min(case when tree.type = 'Poplar' then tree.id end) as poplarid, 
      min(case when tree.type = 'Birch' then tree.id end) as birchid, 
      min(case when tree.type = 'Hazelnut' then tree.id end) as hazelid 
     FROM leaf join 
      branch 
      on leaf.branch_id = branch.id join 
      tree 
      on branch.tree_id = tree.id join 
     group by leaf.id 
    ) lt join 
    leaf 
    on leaf.leaf_id = lt.leaf_id join 
    branch 
    on leaf.branch_id = branch.id join 
    tree 
    on tree.id = branch.tree_id 
where tree.id = coalesce(lt.poplarid, lt.birchid, lt.hazelid) 
ORDER by field(tree.type, 'Poplar', 'Birch', 'Hazelnut')