这发生在 WordPress 中,但这是一个通用的 MySQL 问题。
有两个表,其中一个包含帖子,另一个包含由 ID 链接的元数据。
post_title | ID post_id | meta_key | meta_value
-----------+--- --------+----------+-----------
title | 1 1 | key_1 | aaa
-----------+--- --------+----------+-----------
title | 2 1 | key_2 | bbb
--------+----------+-----------
1 | mykey | 1
--------+----------+-----------
2 | key_n | ccc ddd
我正在尝试对某些列值排序结果,这可能不是为所有行设置的。基本上,我希望首先查看设置了此列/值对的行,然后是所有其他行。每个帖子可能都有一些与之关联的元数据,基于meta_key
和meta_value
对。单个帖子可能有更多键,它们不需要包括我要排序的键。
问题是使用带有 a 的 MySQL 查询WHERE meta_key = mykey
将排除所有不存在此键的帖子。所以我需要一种为所有这些帖子显示默认值的方法,其中不存在此元键。
第一步:很容易选择具有特定元键的所有行:
SELECT
p.ID, p.post_title, p.post_type, p.post_date, m.meta_value
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS m ON p.ID = m.post_id
WHERE
m.meta_key = 'mykey'
第二步:如何选择此 meta_key 不存在的所有行?
这就是我的意思,但这可能是一个糟糕的解决方案:
SELECT
p.ID, p.post_title, p.post_type, p.post_date, "some_default"
FROM wp_posts AS p
WHERE
p.ID NOT IN (
SELECT
p.ID
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS m ON p.ID = m.post_id
WHERE
m.meta_key = 'mykey'
)
第三步:显示组合结果。这可能是UNION
上述两个查询中的一个。
我确信必须有更好的解决方案。更重要的是,我不知道如何指定额外的参数——例如,首先找到具有某些给定元键、标题或类别等的所有帖子,然后按照mykey
上面的说明进行排序。
最终编辑
如果有人感兴趣,这是上下文中的最终解决方案。RedFilter 的回答使之成为可能,再次感谢。
SELECT p1.ID, p1.post_title, p1.post_type, p1.post_date, m1.meta_value AS meta1, meta2
FROM wp_posts AS p1
LEFT JOIN wp_postmeta AS m1 ON m1.post_id = p1.ID
LEFT JOIN wp_term_relationships AS tr0 ON tr0.object_id = p1.ID
LEFT JOIN wp_term_taxonomy AS tt0 ON tr0.term_taxonomy_id = tt0.term_taxonomy_id
LEFT JOIN wp_terms AS t0 ON tt0.term_id = t0.term_id
LEFT JOIN
(
SELECT
p.ID, IF (m.meta_value = 'on', 1, 0) AS meta2
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS m
ON p.ID = m.post_id
and m.meta_key = 'mykey'
) as extra
ON extra.ID = p1.ID
WHERE 1 = 1
AND m1.meta_key = 'some-other-meta-key'
AND p1.post_type IN ('post', 'some-custom-post-type')
AND tt0.taxonomy = 'some-taxonomy'
AND t0.term_id = 'some-id'
ORDER BY meta2 DESC, meta1 ASC, p1.post_date DESC