来自连接表的SQL AND列

时间:2010-08-12 14:46:50

标签: sql mysql

我无法在查询中获得正确的结果。我正在使用Mysql,这是我到目前为止所拥有的:

SELECT cpn, status, title, value_category, rating_category, parts.id 
FROM `vendors` 
INNER JOIN `vendor_parts` ON (`vendors`.`id` = `vendor_parts`.`vendor_id`) 
INNER JOIN `parts` ON (`parts`.`id` = `vendor_parts`.`part_id`) 
WHERE (concat(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,'')) 
  LIKE '%vendor1%'
OR 
CONCAT(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,'')) 
  LIKE '%vendor2%') 
GROUP BY cpn 
HAVING COUNT(cpn)=2 
ORDER BY cpn

问题在于,对于parts表中的某些行,供应商表中有多个相同供应商名称的行。因此,在结果集中,我将获得具有两个vendor1而不是vendor1和vendor2的部件。我正在尝试获得至少包含vendor1和vendor2之一的部分。

有什么想法吗?

4 个答案:

答案 0 :(得分:0)

此处的最佳解决方案是清理供应商表中的数据。我知道这可能是不可能的,但它确实是整合重复行的最佳解决方案。从长远来看,它将使您的生活更轻松。这也意味着您需要清理填充供应商表的代码,以确保它不会输入重复项。

为了弄清楚查询中出现了什么问题,请简化它。找出供应商表的select语句,以便只返回您感兴趣的供应商,然后在上面的内部联接中使用它。

选择vendor.id,vendor.name,vendor.abbreviated_name 来自供应商 其中(concat(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,''))LIKE'%vendor1%'或CONCAT(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,' '))LIKE'%vendor2%')

如果您想从结果集中获取第一个供应商,请使用LIMIT命令。放置ORDER BY以确保您想要的那个是第一个返回的。

或者您可以使用GROUP BY对重复的供应商进行分组。检查coalesce命令以处理空列值等。

答案 1 :(得分:0)

问题归结为SELECT匹配两个vendor1,然后才找到第一个vendor2。

尝试使用UNION:

SELECT cpn, status, title, value_category, rating_category, parts.id  
FROM `vendors`  
INNER JOIN `vendor_parts` ON (`vendors`.`id` = `vendor_parts`.`vendor_id`)  
INNER JOIN `parts` ON (`parts`.`id` = `vendor_parts`.`part_id`)  
WHERE concat(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,''))  
  LIKE '%vendor1%'  
GROUP BY cpn  
HAVING COUNT(cpn)=1
UNION
SELECT cpn, status, title, value_category, rating_category, parts.id  
FROM `vendors`  
INNER JOIN `vendor_parts` ON (`vendors`.`id` = `vendor_parts`.`vendor_id`)  
INNER JOIN `parts` ON (`parts`.`id` = `vendor_parts`.`part_id`)  
WHERE CONCAT(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,''))  
  LIKE '%vendor2%'
GROUP BY cpn  
HAVING COUNT(cpn)=1
ORDER BY cpn

答案 2 :(得分:0)

如前所述,您需要清除供应商表中的重复项,并将给定供应商的所有供应商部件重新映射到不同的供应商ID。我不确定你的问题真的有一个明确的解决方案。最初我认为您可能只能为供应商创建派生表,这些供应商只显示一组不同的供应商并将其加入vendor_parts,如下例所示:

SELECT  
     cpn ,
     status,
     title,
     value_category,
     rating_category,
     parts.id
FROM     
    (select * from vendors where vendors.id in (select id from vendors group by vendors.name)) vendors
    INNER JOIN vendor_parts
    ON       (vendors.id = vendor_parts.vendor_id)
    INNER JOIN parts
    ON       (parts.id = vendor_parts.part_id)
WHERE(
    concat(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,'')) LIKE '%vendor1%'
    OR  CONCAT(IFNULL(vendors.name,''),IFNULL(vendors.abbreviated_name,''))  LIKE '%vendor2%'
    )
GROUP BY cpn
HAVING   COUNT(cpn)=2
ORDER BY cpn

这种方法的问题在于,您可能将供应商部件绑定到具有相同名称和不同ID的两个供应商,如果使用group by来创建派生表,那么当您加入时,该表将最终丢失某些供应商部件它到vendor_parts。

我个人会把时间集中在编写更新脚本来清理数据,而不是试图找到解决问题的方法。

享受!

答案 3 :(得分:0)

我可能不合适,但是如果你想找到由vender1和vender2提供的零件,最好的策略是使用连接

SELECT cpn, status, title, value_category, rating_category, parts.id
from `parts`
inner join 
   (
       select distinct part_id from `vender_parts` join ON (`vendors`.`id` = `vendor_parts`.`vendor_id`) 
      WHERE concat(IFNULL(`vendors`.`name`,''),IFNULL(`vendors`.`abbreviated_name`,'')) LIKE '%vendor1%'
   ) `vender1` on `vender1`.`part_id` = `parts`.`id`
inner join 
   (
       select distinct part_id from `vender_parts` join ON (`vendors`.`id` = `vendor_parts`.`vendor_id`) 
      WHERE concat(IFNULL(`vendors`.`name`,''),IFNULL(`vendors`.`abbreviated_name`,'')) LIKE '%vendor2%'
   ) `vender2` on `vender2`.`part_id` = `parts`.`id`
group by cpn