在同一个表上使用内部联接进行SQL排序并重命名列

时间:2013-12-06 14:00:53

标签: mysql sql wordpress

我要查询的表格看起来像这样:

| ------------- ** postmeta ** -------------- |
| unique | post_id  | meta_key   | meta_value |
| --------------------------------------------|
| 1      | 1        | number     | 20         |
| 2      | 2        | number     | 10         |
| 3      | 3        | number     | 30         |
| 4      | 1        | key_a      | xxx        |
| 5      | 2        | key_a      | yyy        |
| 6      | 3        | key_a      | zzz        |
| 7      | 1        | key_b      | aaa        |
| 8      | 2        | key_b      | bbb        |
| 9      | 3        | key_b      | bbb        |
| 10     | 1        | key_c      | 111        |
| 11     | 2        | key_c      | 111        |
| 12     | 3        | key_c      | 222        |

想要的结果
鉴于我想找到行key_c = 111这就是我想得到的行:

| ------------------ ** result ** ------------------ |
| post_id  | time   | other  | another | yet_another |
| ---------------------------------------------------|
| 2        | 10     | yyy    | bbb     | 111         |
| 1        | 20     | xxx    | aaa     | 111         |

因此,我希望按post_idmeta_key = key_c AND meta_value = 111开始按time排序,然后根据以下情况重命名这些列...

伪码
另外,我想用case语句选择找到的meta_keys

SELECT
    CASE WHEN meta_key = 'number' THEN meta_value END AS 'time'
    CASE WHEN meta_key = 'key_a' THEN meta_value END AS 'other'
    CASE WHEN meta_key = 'key_b' THEN meta_value END AS 'another'
    CASE WHEN meta_key = 'key_c' THEN meta_value END AS 'yet_another'

当前查询,无法提供输出

SELECT *
FROM postmeta as a
INNER JOIN postmeta as b
    ON a.post_id = b.post_id
WHERE a.meta_key = 'key_c'
    AND a.meta_value = '111'
GROUP BY
    b.post_id
ORDER BY
    CASE WHEN b.meta_key = 'number' THEN b.meta_value+(0) ELSE b.post_id END,
    b.post_id

2 个答案:

答案 0 :(得分:1)

您可以使用不带连接的条件聚合来使您的查询版本工作。

SELECT postid, max(CASE WHEN meta_key = 'number' THEN meta_value END) AS `time`,
       max(CASE WHEN meta_key = 'key_a' THEN meta_value END) AS `other`,
       max(CASE WHEN meta_key = 'key_b' THEN meta_value END) AS `another`,
       max(CASE WHEN meta_key = 'key_c' THEN meta_value END) AS `yet_another`
FROM postmeta pm
GROUP BY pm.post_id
HAVING max(pm.meta_key = 'key_c' AND pm.meta_value = '111') = 1
ORDER BY time desc;

一些笔记。不需要join,这就是我删除它的原因。如果桌子的大小适中,那将会提升性能。

答案 1 :(得分:0)

不是很灵活,但应该适用于上述情况:

select p.post_id,
n.meta_value as 'time',
a.meta_value as 'other',
b.meta_value as 'another',
c.meta_value as 'yet_another'
from postmeta p
left outer join
(
select t.post_id,t.meta_value
from postmeta t
where meta_key = 'number'
) n on n.post_id = p.post_id
left outer join
(
select t.post_id,t.meta_value
from postmeta t
where meta_key = 'key_a'
) a on a.post_id = p.post_id
left outer join
(
select t.post_id,t.meta_value
from postmeta t
where meta_key = 'key_b'
) b on b.post_id = p.post_id
left outer join
(
select t.post_id,t.meta_value
from postmeta t
where meta_key = 'key_c'
) c on c.post_id = p.post_id
where p.meta_key = 'key_c'
and p.meta_value = '111'
order by `time` asc
;