Mysql 在同一表上使用内部联接并重命名列的SQL排序

Mysql 在同一表上使用内部联接并重命名列的SQL排序,mysql,sql,wordpress,Mysql,Sql,Wordpress,我要查询的表如下所示: | ------------- ** postmeta ** -------------- | | unique | post_id | meta_key | meta_value | | --------------------------------------------| | 1 | 1 | number | 20 | | 2 | 2 | number | 10

我要查询的表如下所示:

| ------------- ** 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\u id
meta\u key=key\u c和meta\u value=111的行进行分组,并按
time
排序,并根据以下情况重命名这些列

伪代码
此外,我想用case语句选择找到的
meta_键

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

不太灵活,但应适用于上述情况:

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
;

您可以通过使用条件聚合而不使用联接来使您的查询版本正常工作

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
并不是严格需要的,这就是我删除它的原因。如果表的大小适中,它确实会提高性能。

Wow,没想到这会是那么复杂的queryMAX(如果是这样的话…@草莓sry,我是sql新手,请合作,你就快到了!MAX(如果是meta_key='number'然后meta_value END)时间等。此外,您的唯一id是多余的。您在(
post_id
meta_key
)上有一个非常合适的自然PK。您存储数据的方式称为EAV模型(实体属性值),是一种SQL反模式(因为它需要这样的查询来显示最简单的数据).我不想讨论所有关于这个的论点,但有大约.值得思考。@GarethD这是一个与wordpress相关的问题,所以我希望他们在听。:)但是,是的,可能会更好!非常感谢。虽然我需要将时间转换为unsigned,因为它是一个srting