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