MySQL: порядок по значению из второй таблицы, использовать по умолчанию, если значение не установлено

Это происходит внутри 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. Для одного сообщения может быть больше ключей, и они не должны включать тот, по которому я хочу сортировать.

Проблема в том, что использование запроса 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'

Второй шаг: как выбрать все строки, в которых этот мета_ключ не существует?

Вот что я имею в виду, но это, вероятно, плохое решение:

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 из обоих запросов выше.

Я уверен, что должно быть лучшее решение. Что еще более важно, я не знаю, как указать дополнительные параметры - например. g., сначала найдите все сообщения с заданным мета-ключом, заголовком, категорией и т. д., а затем упорядочите их по указанному 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

person and    schedule 07.11.2013    source источник


Ответы (1)


person    schedule
comment
Вот и все! Благодарю вас! Теперь осталось только придумать, как совместить это с другими условиями, т.е. грамм. получить эти значения mykey только для строк с некоторыми другими meta_key или, возможно, другим соединением с третьей таблицей. - person and; 08.11.2013