1

拥有这张桌子(抱歉,这里似乎无法获得像样的布局):

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, Text=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 行。

然后想象这个例子有 2000 行和 20 个 Mask_xx 字段......

我正在考虑像 IN、LEFT JOIN、JOIN 和临时表这样的 SQL 来执行此操作,但我认为我可能使事情复杂化了太多......

4

3 回答 3

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 中寻找的内容提供更通用的规则?

于 2010-01-19T23:13:09.867 回答
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_dep并且r.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          *

它将清楚地排除其他人,因为他们的 mask_deps 为 30 不在选择结果集中,并且它将排除 pds 不是 30 的行。

于 2010-01-19T23:13:24.983 回答
0

这是我使用的代码类型,它可以工作,但是当我添加更多标准和字段时,我会得到更多巨大的连接,并且在每个连接中也有更多的 AND..OR...OR 序列,因此欢迎任何改进建议!特别是我担心这可能会随着数据增长而变慢?也欢迎分析 sql 服务器必须为我的代码做什么!

现在我有大约 30 个条件/字段和一些为我生成 SQL 查询的 PHP 代码......

但这是该原理的较小示例:

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 = '*');
于 2010-02-08T12:04:13.497 回答