我有以下MySQL表(MySQL 5.6):
联系人
+----+----------------+
| id | email |
+----+----------------+
| 1 | one@domain.tld |
| 2 | two@domain.tld |
+----+----------------+
contact_attributes
+----+-------------+
| id | name |
+----+-------------+
| 1 | name |
| 2 | current_car |
| 3 | car_color |
+----+-------------+
contact_attribute_values
+----+------------+-------------------------+------------+
| id | value | contact_attribute_value | contact_id |
+----+------------+-------------------------+------------+
| 1 | John Doe | 1 | 1 |
| 2 | Eva Milton | 1 | 2 |
| 3 | BMW X3 | 2 | 1 |
| 4 | Volvo XC90 | 2 | 2 |
| 5 | Pink | 3 | 1 |
| 6 | Blue | 3 | 2 |
+----+------------+-------------------------+------------+
有没有办法在MySQL中使用以下架构创建临时表来按属性获取和过滤联系人?
+------------+----------------+------------+-------------+-----------+
| contact_id | contact_email | name | current_car | car_color |
+------------+----------------+------------+-------------+-----------+
| 1 | one@domain.tld | John Doe | BMW X3 | Pink |
| 2 | two@domain.tld | Eva Milton | Volvo XC90 | blue |
+------------+----------------+------------+-------------+-----------+
感谢您的帮助
答案 0 :(得分:3)
您可以创建一个生成此结果的视图:
CREATE VIEW contacts_view AS
SELECT
c.id,
c.email, -- OK to select this since we GROUP BY the primary key
MAX(CASE WHEN ca.name = 'name' THEN cav.value END) AS name,
MAX(CASE WHEN ca.name = 'current_car' THEN cav.value END) AS current_car,
MAX(CASE WHEN ca.name = 'car_color' THEN cav.value END) AS car_color
FROM contacts c
LEFT JOIN contact_attribute_values cav
ON c.id = cav.contact_id
INNER JOIN contact_attributes ca
ON cav.contact_attribute_value = ca.id
GROUP BY
c.id;
你可以创建一个临时表,其中包含上述视图的输出。但是我觉得一个观点更像是你在这之后所拥有的。会话结束后将删除临时表,这意味着您每次都必须再次填充。并且,一旦基础表中的数据发生变化,内部数据就会变得陈旧。
答案 1 :(得分:1)
使用CASE
这样的表达式:
SELECT
v.contact_id,
MAX(CASE WHEN a.name = 'contact_email' THEN v.value ELSE '' END) AS 'contact_email',
MAX(CASE WHEN a.name = 'name' THEN v.value ELSE '' END) AS 'name',
MAX(CASE WHEN a.name = 'current_car' THEN v.value ELSE '' END) AS 'current_car'
MAX(CASE WHEN a.name = 'car_color' THEN v.value ELSE '' END) AS 'car_color'
FROM contacts as c
INNER JOIN contact_attribute_values as v on c.id = v.contact_id
INNER JOIN contact_attributes as a on v.contact_attribute_value = a.id
group by v.contact_id;
你不必记下所有属性,你可以动态地制作它:
SET @cols = NULL;
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(a.name = ''',
a.name, ''', v.value , NULL)) AS ', '''', a.name , '''')
) INTO @cols
FROM contact_attributes a;
SET @sql = CONCAT('SELECT
v.contact_id,', @cols, '
FROM contacts as c
LEFT JOIN contact_attribute_values as v on c.id = v.contact_id
INNER JOIN contact_attributes as a on v.contact_attribute_value = a.id
group by v.contact_id;');
prepare stmt
FROM @sql;
execute stmt;