如何在MySQL中加入这两个表

时间:2016-05-18 13:42:00

标签: mysql sql

我有两个具有以下结构的表:

|=================|
| posts           |
|=================|
| ID | Title      |
|-----------------|
| 1  | Title #1   |
|-----------------|
| 2  | Title #1   |
|-----------------|
| 3  | Title #1   |
|-----------------|
| 4  | Title #1   |
|-----------------|
| 5  | Title #1   |
|-----------------|

|==========================================|
| meta                                     |
|==========================================|
| id | post_id | meta_key   | meta_value   |
|------------------------------------------|
| 1  | 1       | key_one    | value for #1 |
|------------------------------------------|
| 2  | 1       | key_two    | value for #1 |
|------------------------------------------|
| 3  | 1       | key_three  | value for #1 |
|------------------------------------------|
| 4  | 2       | key_one    | value for #2 |
|------------------------------------------|
| 5  | 2       | key_three  | value for #2 |
|------------------------------------------|
| 6  | 3       | key_one    | value for #3 |
|------------------------------------------|
| 7  | 3       | key_three  | value for #3 |
|------------------------------------------|

我需要获得以下单个结果:

|----------------------------------------------------------------|
| ID | Post Title | Meta Key One | Meta Key Two | Meta Key Three |
|----------------------------------------------------------------|
| 1  | Title #1   | value for #1 | value for #1 | value for #1   |
|----------------------------------------------------------------|
| 2  | Title #2   | value for #2 | null         | value for #2   |
|----------------------------------------------------------------|
| 3  | Title #3   | value for #3 | null         | value for #3   |
|----------------------------------------------------------------|

但我不知道该怎么做。

我直到现在构建的SQL查询是这样的:

SELECT
   `p`.`ID` AS `ID`,
   `p`.`Title` AS `Post Title`,
   `mt1`.`meta_value` AS `Meta Key One`,
   `mt2`.`meta_value` AS `Meta Key One`,
FROM
    posts AS `p`
    LEFT JOIN `meta` AS `mt1` ON ( `p`.`ID` = `mt1`.`post_id` )
    LEFT JOIN `meta` AS `mt2` ON ( `p`.`ID` = `mt2`.`post_id` )
WHERE
    1 = 1
    AND `mt1`.`meta_key` = 'key_one'
    AND `mt2`.`meta_key` = 'key_three';

问题是如果我在LEFT JOIN表中添加第三个meta以便稍后在WHERE子句中使用它并说mt1.meta_key = 'key_two'我只获得一条记录而不是3。

有谁知道如何通过单个查询实现这一目标?

我不知道这是否有帮助,但我在这里创建了一个SQL小提琴:http://sqlfiddle.com/#!9/af591f/1

请注意,小提琴中的列名称与我的示例中的列名称不相符,但问题仍然存在。

4 个答案:

答案 0 :(得分:4)

您可以使用条件聚合

SELECT p.ID, p.Title AS 'Post Title',
       MAX(CASE WHEN meta_key = 'key_one' THEN meta_value END) AS 'Meta Key One',
       MAX(CASE WHEN meta_key = 'key_two' THEN meta_value END) AS 'Meta Key Two',
       MAX(CASE WHEN meta_key = 'key_three' THEN meta_value END) AS 'Meta Key Three'
FROM posts AS p
LEFT JOIN meta AS m ON p.ID = m.post_id
GROUP BY p.ID, p.Title

此方法的好处是您只使用LEFT JOIN一次,因此可以轻松扩展以容纳其他键值。

Demo here

答案 1 :(得分:2)

http://sqlfiddle.com/#!9/af591f/4

SELECT 
  `b`.`id` AS `ID`,
  `b`.`title` AS `Title`,
  mt1.meta_value `KeyOne`,
  mt2.meta_value `KeyTwo`,
  mt3.meta_value `KeyThree`
FROM 
  `base` as `b`
  LEFT JOIN `meta` mt1 ON b.id = mt1.base_id AND mt1.meta_key = 'key_one' 
  LEFT JOIN `meta` mt2 ON b.id = mt2.base_id AND mt2.meta_key = 'key_two' 
  LEFT JOIN `meta` mt3 ON b.id = mt3.base_id AND mt3.meta_key = 'key_three' 

答案 2 :(得分:1)

您按列连接表,不按列连接列。由于您只有两个表,因此只需要一个连接。从此查询开始,将*更改为您需要的任何列。

select 
    * --or whatever
from
posts p
left join meta m on p.id = m.post_id

答案 3 :(得分:1)

试试这个:

SELECT
   `p`.`ID` AS `ID`,
   `p`.`Title` AS `Post Title`,
   `mt1`.`meta_value` AS `Meta Key One`,
   `mt2`.`meta_value` AS `Meta Key Two`,
   `mt3`.`meta_value` AS `Meta Key Three`
FROM
    posts AS `p`
    LEFT JOIN `meta` AS `mt1` 
        ON ( `p`.`ID` = `mt1`.`post_id` AND `mt1`.`meta_key` = 'key_one')
    LEFT JOIN `meta` AS `mt2` 
        ON ( `p`.`ID` = `mt2`.`post_id` AND `mt2`.`meta_key` = 'key_two')
    LEFT JOIN `meta` AS `mt3` 
        ON ( `p`.`ID` = `mt3`.`post_id` AND `mt3`.`meta_key` = 'key_three')