2010-01-19 24 views
1

有了这个表(对不起,不能似乎在这里得到一个体面的布局):整蛊SQL SELECT的问题(MySQL的)

PD  Header   Text    Mask_Producer  Mask_Dep  Mask_Diam 
---------------------------------------------------------------------------------------------- 
10  Producer  Aproducer   Aprod    *    * 
10  Producer  Bproducer   Bprod    *    * 
20  Diam   A     Aprod    10    30 
20  Diam   A     Aprod    20    40 
20  Diam   B     Aprod    10    40 
30  Dep   10    Aprod    10    * 
30  Dep   20    Aprod    20    * 
30  Dep   30    Aprod    30    * 
20  Diam   A     Bprod    20    40 
30  Dep   10    Bprod    10    * 

我正在使用的表作为过滤器/屏蔽该行选择其他行。

所以,用户在已经做出了选择行有:

PD Text 
------------- 
10 Aproducer 
20 A 

我现在想找出什么行与PD = 30适合那些以前的选择:

PD = 10,文本= Aproducer给出了Mask_Producer必须是“Aprod”,(Mask_Dep和Mask_Diam被允许为星星的任何东西)

PD = 20,Text = A给出Mask_Producer必须是“Aprod”并且Mask_Dep必须是10或20和Mask_Diam必须是30或40(或星号)

我希望结果是上表中的第6行和第7行。

然后想象与2000rows和20个Mask_xx领域这个例子....

我想SQL像IN,LEFT JOIN,连接和临时表要做到这一点,但我想我可能太复杂的东西很多....

+0

使数据代码(4位),所以在等宽它至少呈现。 – 2010-01-19 22:59:39

+0

感谢您不使用标签 - 降价语法:http://stackoverflow.com/editing-help – 2010-01-19 23:00:16

+1

我不明白你试图在你的查询中捕获什么规则。例如,为什么第6行和第7行是所需的输出?我没有看到这种模式。 – recursive 2010-01-19 23:03:03

回答

0

这是我使用的代码类型,它的工作原理,但随着我添加更多的标准和字段,我得到更多的大连接,并且在每个连接中还有更多的AND或OR序列,所以任何改进的命题都是值得欢迎的!特别是,我认为这可能是缓慢的数据交流?分析sql服务器为我的代码做什么也是受欢迎的!

现在我有大约30个标准/领域和一些PHP代码,为​​我生成SQL查询....

但这里是为原则的小例子:

SELECT DISTINCT t30.* 
FROM 
    (SELECT * 
    FROM YourTable 
    WHERE PD = 10 
    AND Text = 'Aproducer') AS t10 
JOIN 
    (SELECT * 
    FROM YourTable 
    WHERE PD = 20 AND Text = 'A') AS t20 ON 
    (t20.MaskProducer = t10.MaskProducer 
           OR t20.MaskProducer = '*' 
           OR t10.MaskProducer = '*') 
    AND (t20.MaskDep = t10.MaskDep 
           OR t20.MaskDep = '*' 
           OR t10.MaskDep = '*') 
    AND(t20.MaskDiam = t10.MaskDiam 
           OR t20.MaskDiam = '*' 
           OR t10.MaskDiam = '*') 
//more JOINS like the one above for each criteria 
// below the final join to get the result from 
JOIN 
    (SELECT * 
    FROM YourTable 
    WHERE PD = 30) AS t30 ON 
     (t30.MaskProducer = t20.MaskProducer 
          OR t30.MaskProducer = '*' 
          OR t20.MaskProducer = '*') 
     AND (t30.MaskDep = t20.MaskDep 
          OR t30.MaskDep = '*' 
          OR t20.MaskDep = '*') 
     AND (t30.MaskDiam = t20.MaskDiam 
          OR t30.MaskDiam = '*' 
          OR t20.MaskDiam = '*'); 
1

我想我明白你在问什么,但我更熟悉SQL Server,所以如果我的语法稍微偏离请原谅我。你应该能够做一个内部联接,将表加入自己以获得你想要的结果。

SELECT * 
FROM tbData A 
JOIN tbData B ON A.PD = B.Mask_Dep AND A.Mask_Producer=B.Mask_Producer 
WHERE A.PD = 10 
    AND A.Text='Aproducer' 
UNION 
SELECT * 
FROM tbData A 
JOIN tbData B ON A.PD = B.Mask_Dep AND A.Mask_Producer=B.Mask_Producer 
WHERE A.PD = 20 
    AND A.Text='A' 

看着这我觉得我有点偏离,但你的一些数据不清楚。你能否给出你在Mask_Dep和Mask_Diam中寻找的更多通用规则?

+0

嗨,你可能会对某事,但A.PD = B.Mask_Dep显然是不正确的,这些领域是无关的。 – 2010-01-21 08:49:46

+0

点采取。似乎A.PD和B.PD的规则是不同的。是这样吗?如果不是,你能给我一个统一的规则吗?我想如果你能的话我可以帮你。 – 2010-01-21 14:28:30

+0

找到了解决方法从其他来源(rob_farley): SELECT t30。* FROM(SELECT * FROM YourTable WHERE PD = 10 AND Text ='Aproducer')as t10 JOIN(SELECT * FROM YourTable where PD = 20 AND Text =' A')as t20 ON(t20.MaskProducer = t10.MaskProducer OR t20.MaskProducer ='*'OR t10.MaskProducer ='*')AND(t20.MaskDep = t10.MaskDep OR t20.MaskDep ='*'OR t10 .MaskDep ='*')AND(t20.MaskDiam = t10.MaskDiam OR t20.MaskDiam ='*'OR t10.MaskDiam ='*') ...继续下一条评论.... – 2010-01-22 06:58:01

1

我想你想是这样的:

SELECT r.* FROM table AS c -- choices 
JOIN table AS r   -- results 
    ON (
     (r.mas_dep = '*' OR c.mask_dep = r.mask_dep) 
     AND 
     (r.mask_diam = '*' OR c.mask_diam = r.mask_diam) 
    ) 
WHERE (
    (c.pd = 10 AND c.text = 'Aproducer') 
    OR (c.pd = 20 AND c.text = 'A') 
) 
AND r.PD = 30 

这将需要的选择的结果:

PD  Header   Text   Mask_Producer Mask_Dep Mask_Diam 
10  Producer  Aproducer Aprod   *   * 
20  Diam    A   Aprod   10   30 
20  Diam    A   Aprod   20   40 

和自加入它针对主表,在这些条件保持为真r.mas_dep = '*' OR c.mask_dep = r.mask_depr.mask_diam = '*' OR c.mask_diam = r.mask_diam。这将返回一组:

PD  Header   Text   Mask_Producer Mask_Dep Mask_Diam 
30  Dep    10   Aprod   10   * 
30  Dep    20   Aprod   20   * 

它会排除其他明确,因为他们的30 mask_deps是不是在选择结果集,这将排除行PDS而不是30

+0

这看起来像你打倒我!将思考并尝试让你知道。谢谢你,现在睡觉... ;-) – 2010-01-20 00:14:38

+0

嗨,埃文,现在测试,几乎可以工作! ....如果我添加这些行#9:“20 Diam A Bprod 20 40”和#10:“30 Dep 10 Bprod 10 *”我将在选择中得到#9(错误),然后还包括#10结果(错误)....有什么建议? – 2010-01-21 08:44:33