假设我在MySQL数据库中有两个表。
表格1:
ID Name 1 Jim 2 Bob 3 John
表2:
ID key value 1 address "X Street" 1 city "NY" 1 region "NY" 1 country "USA" 1 postal_code "" 1 phone "123456789"
从数据库中选择行时,是否有任何方法可以将第二个表中的行作为列连接到第一个表中?
直接从MySQL查询获得的期望结果是:
ID Name address city region country postal_code phone 1 Jim X Street NY NY USA NULL 123456789 2 Bob NULL NULL NULL NULL NULL NULL 3 John NULL NULL NULL NULL NULL NULL
谢谢你的帮助!
这种数据转换类型称为PIVOT。MySQL没有枢轴函数,但是您可以使用带有CASE表达式的聚合函数来复制它:
CASE
select t1.id, t1.name, max(case when t2.`key` = 'address' then t2.value end) address, max(case when t2.`key` = 'city' then t2.value end) city, max(case when t2.`key` = 'region' then t2.value end) region, max(case when t2.`key` = 'country' then t2.value end) country, max(case when t2.`key` = 'postal_code' then t2.value end) postal_code, max(case when t2.`key` = 'phone' then t2.value end) phone from table1 t1 left join table2 t2 on t1.id = t2.id group by t1.id, t1.name
请参阅带有演示的SQL Fiddle。
这也可以使用您的多个联接来编写,table2并且您将在每个联接的联接上包括一个过滤器key:
table2
key
select t1.id, t1.name, t2a.value address, t2c.value city, t2r.value region, t2y.value country, t2pc.value postal_code, t2p.value phone from table1 t1 left join table2 t2a on t1.id = t2a.id and t2a.`key` = 'address' left join table2 t2c on t1.id = t2c.id and t2c.`key` = 'city' left join table2 t2r on t1.id = t2r.id and t2c.`key` = 'region' left join table2 t2y on t1.id = t2y.id and t2c.`key` = 'country' left join table2 t2pc on t1.id = t2pc.id and t2pc.`key` = 'postal_code' left join table2 t2p on t1.id = t2p.id and t2p.`key` = 'phone';
如果key值的数量有限,则上述两个版本将非常有用。如果您有未知数量的值,那么您将需要查看使用准备好的语句来生成动态SQL:
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'max(case when t2.`key` = ''', `key`, ''' then t2.value end) AS `', `key`, '`' ) ) INTO @sql from Table2; SET @sql = CONCAT('SELECT t1.id, t1.name, ', @sql, ' from table1 t1 left join table2 t2 on t1.id = t2.id group by t1.id, t1.name;'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
参见带有演示的SQL Fiddle
所有版本都会给出结果:
| ID | NAME | ADDRESS | CITY | REGION | COUNTRY | POSTAL_CODE | PHONE | |----|------|----------|--------|--------|---------|-------------|-----------| | 1 | Jim | X Street | NY | (null) | (null) | (null) | 123456789 | | 2 | Bob | (null) | (null) | (null) | (null) | (null) | (null) | | 3 | John | (null) | (null) | (null) | (null) | (null) | (null) |