Reputation: 2917
I have stored data into several MySQL 5.x tables in order to normalize, now I am struggling on how to retrieve this data in one line per dataset.
E.g.
Table 1: articles, holding also 2 values in this example per article
article_id | make | model
1 Audi A3
Table 2: article_attributes, where one article can have several attributes
article_id | attr_id
1 1
1 2
2 1
Table 3: article_attribute_names
attr_id | name
1 Turbo
2 Airbag
Now I want to retrieve it, with one line per dataset
e.g.
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
This will gives me:
article_id | Make | Model | function
1 Audi A3 Turbo
1 Audi A3 Airbag
But I am looking for something like this:
article_id | Make | Model | function1 | function2
1 Audi A3 Turbo Airbag
Is this even possible, and if yes, how?
Upvotes: 0
Views: 62
Reputation: 1270503
The simplest method is to put the values into a delimited field using 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;
Aggregating by article_id
is okay, assuming that the id is unique (or equivalently declared as a primary key).
If you actually want the results in separate columns, that is more challenging. If you know there are at most two (as in your example), just use aggregation:
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;
Upvotes: 2