如何在MySQL中连接这两个表

如何在MySQL中连接这两个表,mysql,sql,Mysql,Sql,我有两个表,结构如下: |=================| | posts | |=================| | ID | Title | |-----------------| | 1 | Title #1 | |-----------------| | 2 | Title #1 | |-----------------| | 3 | Title #1 | |-----------------| | 4 | Title #1

我有两个表,结构如下:

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

我需要得到以下单一结果:

|----------------------------------------------------------------|
| 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';
问题是,如果我在
meta
表中添加第三个
LEFT JOIN
,稍后在
WHERE
子句中使用它,并说
mt1.meta\u key='key\u two'
我只得到一条记录,而不是三条

有人知道我如何通过一个查询实现这一点吗

我不知道这是否有帮助,但我在这里创建了一个SQL FIDLE:


请注意,fiddle中的列名与我的示例中的列名不符,但问题仍然相同。

您按列联接表,而不是按列联接列。。因为只有两个表,所以只需要一个联接。从这个查询开始,将
*
更改为您需要的任何列

select 
    * --or whatever
from
posts p
left join meta m on p.id = m.post_id
您可以为此使用条件聚合:

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
此方法的好处是只需使用一次
左连接
,因此它很容易扩展以容纳其他键值

试试这个:

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')


为此,您应该使用外部联接,因为否则您将无法获得第二和第三个所需的输出行。您可以检查:
左联接
左外部联接
之间没有区别。一般规则是:外部联接表上的条件属于
on
子句,而不是
WHERE
子句。这就是查询失败的地方。
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')
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'