0

这发生在 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_keymeta_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
4

1 回答 1

2
SELECT p.ID, p.post_title, p.post_type, p.post_date, 
    ifnull(m.meta_value, 'default val') as meta_value
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS m ON p.ID = m.post_id 
    and m.meta_key = 'mykey'
于 2013-11-07T14:40:02.440 回答