So wählen Sie Beiträge mit bestimmten Tags/Kategorien in WordPress aus

Lesezeit: 4 Minuten

Benutzeravatar von yoavf
yoavf

Dies ist eine sehr spezifische Frage bzgl MySQL wie implementiert in WordPress.

Ich versuche, ein Plugin zu entwickeln, das (ausgewählte) Beiträge anzeigt, die bestimmte ‘Stichworte‘ und gehören zu bestimmten ‘Kategorien‘ (beide mehrfach)

Mir wurde gesagt, dass dies aufgrund der Art und Weise, wie Kategorien und Tags gespeichert werden, unmöglich ist:

  1. wp_posts enthält eine Liste von Posts, jeder Post hat eine “ID”
  2. wp_terms enthält eine Liste von Begriffen (sowohl Kategorien als auch Tags). Jeder Begriff hat eine TERM_ID
  3. wp_term_taxonomy hat eine Liste von Begriffen mit ihren TERM_IDs und hat eine Taxonomie-Definition für jeden davon (entweder eine Kategorie oder ein Tag)
  4. wp_term_relationships hat Assoziationen zwischen Begriffen und Beiträgen

Wie kann ich den Tischen beitreten, um alle Beiträge mit den Tags „Nuklear“ zu erhalten? und „Angebote“, die auch zur Kategorie „Kategorie1“ gehören?

Benutzeravatar von Eric
Erich

Ich habe dich missverstanden. Ich dachte, Sie wollten Nuclear oder Deals. Das Folgende sollte Ihnen nur Nuklear und Deals geben.

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")

Benutzeravatar von Eric
Erich

Versuche dies:

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'))

Im Wesentlichen verwende ich 2 Kopien der relevanten untergeordneten Tabellen – terms, term_taxonomy und term_relationship. Eine Kopie wendet die Beschränkung „Kategorie 1“ an, die andere die Beschränkung „Nuklear“ oder „Deals“.

Übrigens, was ist das für ein Projekt mit Beiträgen rund um Atomabkommen? Versuchen Sie, uns auf irgendeine Regierungsliste zu setzen? 😉

  • Dies ist eine fantastische Lösung

    – Lenin Zapata

    25. Juni 2019 um 6:17 Uhr

Was für eine grobe DB-Struktur.

Wie auch immer, ich würde so etwas tun (beachten Sie, dass ich EXISTS Joins vorziehe, aber Sie können sie als Joins umschreiben, wenn Sie möchten; die meisten Abfrageanalysatoren werden sie sowieso auf denselben Abfrageplan reduzieren). Möglicherweise müssen Sie auf die eine oder andere Weise zusätzlich jonglieren, damit es funktioniert …

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" 
                                           )
                            )
            )

Benutzeravatar von Scott Gotttreu
Scott Gotttreu

Also habe ich beide Optionen auf meiner WordPress-Datenbank ausprobiert. Ich habe in meinen Beiträgen mit den Tags “Perl” UND “Programmierung” nach der Kategorie “Tech” gesucht.

Eric hat funktioniert, nachdem ich ein fehlendes Komma in der ersten select-Anweisung hinzugefügt hatte. Es wurden 3 Datensätze zurückgegeben. Das Problem ist, dass der Abschnitt, der nach dem “post_tag” sucht, tatsächlich als ODER-Option fungiert. Einer meiner Beiträge hatte nur einen Tag, nicht beide. Es wäre auch gut, das SELECT DISTINCT zu machen.

Ich habe Matts Version ausprobiert, aber es gab immer wieder ein leeres Set zurück. Ich kann versuchen, damit zu “jonglieren”.

Danke @Eric es funktioniert! Nur ein paar Code-Korrekturen zum späteren Nachschlagen:

  • Bei den ersten Select-Anweisungen fehlt ein Komma nach wp_term_relationship tr2
  • In derselben Select-Anweisung muss Folgendes geändert werden:
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship 

tr2

sollte sein

wp_terms t3, wp_term_taxonomy tt3, wp_term_relationship 

tr3

Wirklich so tolle Antwort.. hat mir sehr geholfen..

großartig, bcoz., es gab mir einen grundlegenden Ansatz, um meine komplexe Abfrage zu erstellen!

Eine kleine Korrektur, für bereite Benutzer wie mich 🙂

“wp_term_relationship” gibt den Fehler “existiert nicht” .. use wp_term_relationships da es der richtige Tabellenname ist.

Danke Erich

1393570cookie-checkSo wählen Sie Beiträge mit bestimmten Tags/Kategorien in WordPress aus

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy