Mysql查询/子查询

时间:2014-08-26 22:04:21

标签: php mysql

我试图使现有数据库和系统符合我们现在从制造商处收到的数据。它的格式无法改变。它是一个表格,其中包含来自单个制造商的产品编号(item_id),这些产品编号来自多个制造商的交叉参考零件(oem_code)。

表:外部参照

item_id   | oem_code
   A      |    123
   A      |    234
   B      |    234
   B      |    345
   C      |    456  

表:部分(仅显示相关的partNum列)

partNum  
  S.A  
  S.B  
  S.C  
  123  
  234  
  345  
  456  

两个外部参照列都包含零件表中的零件号。我需要输入部件号($fielddata),然后从parts.partNum = $fielddata的部件中检索所有数据,并从xref中匹配parts.partNum的所有交叉引用数字。不幸的是,制造商提供的部件号为S。在他们的系统之前,但不在他们发送的表中。我们的系统在没有S的情况下无法识别它们。

MySQL查询

SELECT * 
FROM parts
WHERE partNum
IN (    
    SELECT oem_code
    FROM xref
    WHERE item_id = ( 
        SELECT item_id
        FROM xref 
        WHERE oem_code = '$fielddata' 
    )
)

123返回部件中所有数据,其中parts.partNum = 123,234(也需要S.A)
234错误输出,#1242 - 子查询返回超过1行(需要234,S.A,S.B)
A什么都不返回(需要123,234,S.A)
S.A也没有返回任何内容(需要123,234,S.A)

我理解我的sql语句和子查询的局限性以及为什么我没有得到所需的完整结果集,但我不知道如何扩展它以获得我想要的东西。我很乐意尽我所能。当我尝试扩展它时,我会得到不希望的结果或错误,所以我几乎已经完成了我的能力。

我也知道在大型数据库上运行子查询并不高效。因此,我完全重写了sql或修改了我迄今为止所获得的内容。外部参照有>27k行,部分有>550k行,有10列(如果有人关心的话)。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

使用exists

的查询
SELECT *
FROM parts
WHERE EXISTS (
    SELECT 1 FROM xref x1
    JOIN xref x2 ON x1.item_id = x2.item_id
    WHERE (x2.oem_code = '$fielddata' OR x2.item_id = RIGHT('$fielddata',1))
    AND (x1.oem_code = partNum OR CONCAT('S.',x1.item_id) = partNum)
)

<强>更新

对于给定的$fielddata,针对派生表加入可能会更快。这实际上是@ JohnRuddell的查询,但修改为使用派生表。

SELECT p.* FROM parts p
JOIN (
    SELECT x.oem_code partNum
        FROM xref x
        JOIN xref x1 
          ON x1.item_id = x.item_id 
         AND x1.oem_code = '$fielddata'
          OR x.item_id = RIGHT('$fielddata', 1)
    UNION
    SELECT CONCAT('S.', x.item_id) partNum
        FROM xref x
        WHERE x.oem_code = '$fieldata' 
           OR x.item_id = RIGHT('$fielddata', 1)
) t1 ON t1.partNum = p.partNum

答案 1 :(得分:1)

我认为这应该做你想做的事情

SELECT * 
FROM parts
WHERE partNum IN 
(   SELECT x.oem_code
    FROM xref x
    JOIN xref x1 
      ON x1.item_id = x.item_id 
     AND x1.oem_code = '$fielddata'
      OR x.item_id = RIGHT('$fielddata', 1)
)
OR partNum IN 
(   SELECT CONCAT('S.', x.item_id)
    FROM xref x
    WHERE x.oem_code = '$fieldata' 
       OR x.item_id = RIGHT('$fielddata', 1)
)

DEMO

只使用连接,这样你就不会做第三个子查询