我有两个具有以下结构的表:
|=================|
| 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
请注意,小提琴中的列名称与我的示例中的列名称不相符,但问题仍然存在。
答案 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
一次,因此可以轻松扩展以容纳其他键值。
答案 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')