Pergunta

Esta é uma questão muito específica em relação MySQL conforme implementado em WordPress.

Estou tentando desenvolver um plugin que mostre (selecione) postagens que possuem 'Tag'e pertencem a 'específicos'categorias' (ambos múltiplos)

Disseram-me que é impossível porque a forma como as categorias e tags são armazenadas:

  1. wp_posts contém uma lista de postagens, cada postagem tem um "ID"
  2. wp_terms contém uma lista de termos (categorias e tags).Cada termo tem um TERM_ID
  3. wp_term_taxonomy possui uma lista de termos com seus TERM_IDs e possui uma definição de taxonomia para cada um deles (uma categoria ou uma tag)
  4. wp_term_relationships tem associações entre termos e postagens

Como posso juntar as tabelas para obter todos os posts com tags "Nuclear" e "Ofertas" que também pertencem à categoria "Categoria1"?

Foi útil?

Solução

Eu te entendi mal.Achei que você queria Nuclear ou Deals.O texto abaixo deve fornecer apenas Nuclear e negócios.

select p.*
from wp_posts p, wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr,
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2

where p.id = tr.object_id and t.term_id = tt.term_id and tr.term_taxonomy_id = tt.term_taxonomy_id

and p.id = tr2.object_id and t2.term_id = tt2.term_id and tr2.term_taxonomy_id = tt2.term_taxonomy_id

and p.id = tr3.object_id and t3.term_id = tt3.term_id and tr3.term_taxonomy_id = tt3.term_taxonomy_id

and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name = 'Nuclear')
and (tt3.taxonomy = 'post_tag' and tt3.term_id = t3.term_id and t3.name = 'Deals')

Outras dicas

Que estrutura bruta de banco de dados.

De qualquer forma, eu faria algo assim (observe que prefiro EXISTS a junções, mas você pode reescrevê-las como junções, se desejar;a maioria dos analisadores de consulta irá recolhê-los para o mesmo plano de consulta de qualquer maneira).Você pode ter que fazer alguns malabarismos adicionais de uma forma ou de outra para que funcione ...

SELECT *
  FROM wp_posts p
 WHERE EXISTS( SELECT *
                 FROM wp_term_relationship tr
                WHERE tr.object_id = p.id
                  AND EXISTS( SELECT *
                                FROM wp_term_taxonomy tt
                               WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
                                 AND tt.taxonomy         = 'category'
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Category1" 
                                           )
                            )
                  AND EXISTS( SELECT *
                                FROM wp_term_taxonomy tt
                               WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
                                 AND tt.taxonomy         = 'post_tag'
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Nuclear" 
                                           )
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Deals" 
                                           )
                            )
            )

Então tentei as duas opções no meu banco de dados WordPress.Procurei a categoria "Tech" em meus posts com as tags "Perl" AND "Programming".

Érico funcionou depois que adicionei uma vírgula ausente na instrução select inicial.Ele retornou 3 registros.O problema é que a seção que procura o "post_tag" está na verdade funcionando como uma opção OR.Uma das minhas postagens tinha apenas uma tag, não ambas.Também seria bom fazer o SELECT DISTINCT.

tentei Matt versão, mas continuou retornando um conjunto vazio.Posso tentar "fazer malabarismos" com isso.

Experimente isto:

select p.*
from wp_posts p, 
wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2

where p.id = tr.object_id
and t.term_id = tt.term_id
and tr.term_taxonomy_id = tt.term_taxonomy_id

and p.id = tr2.object_id
and t2.term_id = tt2.term_id
and tr2.term_taxonomy_id = tt2.term_taxonomy_id

and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name in ('Nuclear', 'Deals'))

Essencialmente, estou empregando 2 cópias das tabelas filho pertinentes - termos, term_taxonomia e term_relationship.Uma cópia aplica a restrição 'Categoria1', a outra a restrição 'Nuclear' ou 'Negócios'.

Aliás, que tipo de projeto é esse com postagens sobre acordos nucleares?Você está tentando nos incluir em alguma lista do governo?;)

Obrigado @Eric, funciona!Apenas algumas correções de código para referência futura:

  • as primeiras instruções selecionadas perdem o coma após wp_term_relationship tr2
  • Na mesma instrução select, o seguinte deve ser alterado:
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship 

tr2

deveria estar

wp_terms t3, wp_term_taxonomy tt3, wp_term_relationship 

tr3

Realmente uma ótima resposta ..me ajudou muito..

ótimo bcoz., me deu uma abordagem básica para construir minha consulta complexa!

uma pequena correção, para usuários prontos como eu :)

"wp_term_relationship" dará "erro não existe" ..usar wp_term_relationships pois é o nome correto da tabela.

Obrigado Érico

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top