如何从规范化表中每个数据集中一行检索值?

时间:2018-12-29 16:36:47

标签: mysql sql

我已经将数据存储到几个MySQL 5.x表中以进行规范化,现在我在努力如何在每个数据集中一行中检索此数据。

例如

表1:文章,在此示例中,每篇文章也包含2个值

article_id | make | model
1            Audi   A3

表2:article_attributes ,其中一篇文章可以具有多个属性

article_id | attr_id
1            1
1            2
2            1

表3:article_attribute_names

attr_id | name
1         Turbo
2         Airbag

现在我要检索它,每个数据集一行

例如

SELECT a.*, attr_n.name AS function
FROM `articles` a
LEFT JOIN article_attributes AS attr ON a.article_id = attr.article_id
LEFT JOIN article_attribute_names AS attr_n ON attr_n.attr_id = attr.attr_id
-- group by attr.article_id

这会给我:

article_id | Make | Model  | function
1            Audi   A3       Turbo
1            Audi   A3       Airbag

但是我正在寻找这样的东西:

article_id | Make | Model  | function1 | function2
1            Audi   A3       Turbo       Airbag

这是否有可能,如果可以,怎么办?

1 个答案:

答案 0 :(得分:2)

最简单的方法是使用group_concat()将值放入分隔的字段中:

SELECT a.*, GROUP_CONCAT(an.name) AS functions
FROM articles a LEFT JOIN
     article_attributes aa
     ON a.article_id = aa.article_id LEFT JOIN
     article_attribute_names aan
     ON aan.attr_id = aa.attr_id
GROUP BY a.article_id;

通过article_id进行聚合是可以的,假设id是唯一的(或等效地声明为主键)。

如果您实际上希望将结果放在单独的列中,则更具挑战性。如果您知道最多两个(如您的示例所示),请使用聚合:

SELECT a.*, MIN(an.name) AS function1,
       (CASE WHEN MIN(an.name) <> MAX(an.name)
             THEN MAX(an.name)
        END) as function2
FROM articles a LEFT JOIN
     article_attributes aa
     ON a.article_id = aa.article_id LEFT JOIN
     article_attribute_names aan
     ON aan.attr_id = aa.attr_id
GROUP BY a.article_id;