SQL:JOIN和其他表的基础知识

时间:2011-12-13 17:06:25

标签: mysql sql join multiple-tables

我想我需要提示去哪个方向。 跟进我的other question,我正在尝试使用 MySQL 在3个表上实现sql查询。

表1:产品上的“基础”信息

id, productnumber
1,45

表2:每个产品ID的“country_specifics”

id, countrycode,name
1,"DE","Produkt 1"
1,"US","Product 1"

好的,

SELECT B.id,C.name,C.countrycode 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';

给了我想要的东西:

1,"Product 1","US"

BUT:

我有第三张表:

表3:每个产品ID的“功能”

id,feature
1,"feature 1"
1,"feature 2"

并且我的查询的最终结果应该以某种方式另外包含产品的功能。 我尝试了另外的

INNER JOIN features AS F ON b.id=f.id

但是会返回两行(我理解为什么):

1,"Product 1","US","feature 1"
1,"Product 1","US","feature 2"

但我认为这不是我想要的。 我想要的是一个特征字段的数组:

1,“产品1”,“美国”,“功能1,功能2”

结果是

。我知道(或者相当肯定)SQL中没有数组,但最接近的是什么?我可以在1个查询中执行此操作吗?显然,我可以简单地开始第二个查询,但这是最好的选择吗? 我应该google哪个关键字?

感谢阅读,马林巴

修改

非常感谢大家的帮助!

我只是想澄清一下我的问题:我不一定需要一个数组或接近它的东西。我想了解获得“此产品的所有数据”的最佳(最有效,最不容易出错)的方法。

如果你告诉我接受2行作为结果并且使用它是最好的方法,我会这样做。 我只是想当他们设计SQL时,他们想到了这个问题并准备好了解决方案,我正试图找到解决方案。

编辑2:

再一次,我为误导人们认为我需要一个以逗号分隔的字符串而道歉。我试图说明我期待的数据类型。

我很欣赏指向group_concat的指针,但我感觉有一个stored procedure有2个查询,正如jmacinnes和Sachin所概述的那样,是更清洁的方式。

谢谢stackoverflow社区。

5 个答案:

答案 0 :(得分:2)

您可以编写一个带有id的函数或存储过程,然后对于features表返回一个包含该id的所有功能的字符串。然后,您可以在原始查询中使用它。

答案 1 :(得分:1)

我认为您应该使用已编写的单个查询来执行此操作。然后,只需格式化要在应用程序层中以所需方式显示的数据。您可以遍历结果并将每个产品的所有功能组合在一起。

虽然可以返回你所追求的结果集,但这样做是不好的做法。如果功能表在将来发生变化,它将使解析数据变得更加困难。

如果通过加入Features表获得的重复数据很重要,那么您可以在一个存储过程中返回两个结果集:

SELECT B.id,C.name,C.countrycode 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';

SELECT id featureId FROM features where ProductId = 1

答案 2 :(得分:1)

因为您使用的是MySQL,所以可以使用group_concat:

SELECT B.id,C.name,C.countrycode, group_concat(F.feature) as feature_list 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US'
INNER JOIN features AS F ON B.id=F.id
GROUP BY B.id

答案 3 :(得分:1)

以下解决方案基于Oracle,您可以尝试在MySQL中实现相同的

您可以创建数据库功能,如下所示

create or replace function prod_feature(p_product_id in number) return varchar2
    v_feature varchar2(2000) := '';
    i number := 0 ;
begin
    for c1rec in (select feature from table3 where product_id = p_product_id) loop
       if i = 0 then
           v_feature:= v_feature|| c1rec.feature;
       else
           v_feature:= v_feature|| ', ' || c1rec.feature;
       end if;
       i  := i +1;
    end loop;
    return v_feature;
end; 

然后在第一个sql中使用此函数

SELECT B.id,C.name,C.countrycode, prod_feature(id) 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';

答案 4 :(得分:0)

这个怎么样?试试这个,看看它是否按你想要的方式工作。

SELECT id, name, code, GROUP_CONCAT(fea) features FROM 
(  
  SELECT id, name, code, f.feature fea FROM 
  (
    SELECT b.id id, cs.name name, cs.countrycode code FROM 
    base b
    JOIN country_specifics cs
    ON cs.id = b.id
    AND cs.countrycode = "US"
   ) a
 JOIN features f
 ON f.id = a.id  
) b
GROUP BY id