SQL-从联接表排序结果

时间:2018-12-10 22:03:53

标签: mysql join sql-order-by

注意:此问题与WordPress特定问题有关,但我希望从纯SQL角度对此问题有一个“外观”:https://wordpress.stackexchange.com/questions/55263/order-posts-by-custom-field-and-if-custom-field-is-empty-return-remaining-posts

让我们说表必须具有以下结构:

Tabe postsID(密钥),Title

post_metadatapost_ID(FKEY),meta_keymeta_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

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