注意:此问题与WordPress特定问题有关,但我希望从纯SQL角度对此问题有一个“外观”:https://wordpress.stackexchange.com/questions/55263/order-posts-by-custom-field-and-if-custom-field-is-empty-return-remaining-posts
让我们说表必须具有以下结构:
Tabe posts
:ID
(密钥),Title
表post_metadata
:post_ID
(FKEY),meta_key
,meta_value
我想检索具有以下内容的帖子的ID和标题:
post_metadata
中的条目,其中key
='meta_1'和meta_value
='value_1'post_metadata
中输入key
='meta_2'和meta_value
='value_2'我想用meta_key
=“ meta_3”的第三个元数据的值对结果进行排序。
现在这是棘手的部分:
并非所有帖子在post_metadata
表中都有一个条目,其中'meta_3'为meta_key
。由于我不是按meta_3过滤帖子,而是按顺序过滤,因此我想将这些帖子保留在结果中,就好像它们对此meta的值是空的。
我们如何实现?
谢谢
编辑:
现在有SQL提琴:https://www.db-fiddle.com/f/kBNaaRFB5xfna5MniuTpaG/1
答案 0 :(得分:0)
也许:
使用一次左联接来获取meta 3值(如果存在),以确保将具有meta1和meta2的所有帖子保留为期望值。 然后使用一个exist并必须确保您只获取同时具有期望值的meta1和2的记录。
未测试...
SELECT P.ID, P.Title, PM.Meta_value
FROM Posts P
LEFT JOIN Post_MetaData PM
on P.ID = PM.Post_ID
and PM.key = 'meta_3'
WHERE exists (SELECT 1
FROM post_meta
WHERE ((Key 'meta_1' and meta_value = 'Value_1') OR
(Key 'meta_2' and meta_value = 'Value_2'))
and P.ID = Post_ID --Either here or an AND in the HAVING clause...need to test to know
GROUP BY Post_ID
HAVING count(*) = 2 )
ORDER BY -PM.meta_value desc, P.ID
这确实假定post_metaData对每个Post_ID的密钥都有唯一的约束。否则我们可以得到值为a的meta_1和值为a的meta1,而count(*)为2;并在结果中错误地返回它。
为确保最后一个空值,请遵循此方法; MySQL Orderby a number, Nulls last
以IN方式执行此操作...。但我认为这会更慢。
SELECT P.ID, P.Title, PM.Meta_value
FROM Posts P
LEFT JOIN Post_MetaData PM
on P.ID = PM.Post_ID
and PM.key = 'meta_3'
WHERE P.ID in (SELECT Post_meta.Post_ID
FROM post_meta
WHERE ((Key 'meta_1' and meta_value = 'Value_1') OR
(Key 'meta_2' and meta_value = 'Value_2'))
GROUP BY Post_ID
HAVING count(*) = 2 )
ORDER BY -PM.meta_value desc, P.ID