2012-08-16 86 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')