Zur Navigation

Verknüpfte SQL-Abfragen

1 Horst_M

Heute bin ich mit meinen Latein am Ende, weil ich bei verknüpften Anfragen nicht richtig durchblicke. Ist eine WordPress-Abfrage, wobei $wp_query bereits die Anzahl der Treffer und den eingegebenen Suchbegriff enthält und $wpdb die Verbindung zur Datenbank. Die ID von den Posts ist auch vorhanden und die Testausgabe mit dem unteren Listing funktioniert erst einmal soweit.

4 Treffer mit Hula-Hoop
ID: 44 - Titel: Ein neuer Beitrag
ID: 207 - Titel: Zwischenseite
ID: 237 - Titel: HTML Test
ID: 258 - Titel: Code-Schnipsel für Suche

<?php
$anzahl  = $wp_query->found_posts;
$gesucht = $wp_query->query["s"];

echo $anzahl." Treffer mit ".$gesucht."<br />\n<br />\n";

if ($anzahl > 0) {

    $table = $wpdb->prefix."posts";
    $taxon = $wpdb->prefix."term_relationships";
    $suche = $wpdb->get_results("
                    SELECT *
                    FROM ".$table."
                    WHERE post_type = 'post'
                    AND (post_title LIKE '%".$gesucht."%'
                    OR post_content LIKE '%".$gesucht."%')");

    foreach ($suche as $detail) {

        if (isset($detail->post_title)) {
            echo "ID: ".$detail->ID." - ".
                 "Titel: ".$detail->post_title."<br />\n";
        }
    }
}
?>

Nun sollten aber noch die Kategorien angezeigt werden und dabei sieht es wie folgt aus. Die ID nennt sich in der wp_term_relationships nicht mehr ID, sondern object_id und benötigt wird dann die term_taxonomy_id.

INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`, `term_order`) VALUES
(1, 1, 0),
(4, 1, 0),
(30, 1, 0),
(44, 1, 0),
(44, 2, 0),
(58, 1, 0),
(108, 1, 0),
...

Die term_taxonomy_id ist noch nicht allein das Ziel, sondern das Ziel ist eigentlich in der wp_terms der name.

INSERT INTO `wp_terms` (`term_id`, `name`, `slug`, `term_group`) VALUES
(1, 'Allgemein', 'allgemein', 0),
(2, 'post-format-aside', 'post-format-aside', 0),
(3, 'Plugins', 'plugins', 0),
(4, 'Code-Schnipsel', 'code-schnipsel', 0);

Lässt sich das überhaupt irgendwie verknüpfen?
Zumindest erst einmal so weit, dass man term_taxonomy_id von der zweiten Tabelle erhalten könnte?

Ging nur um eine Frage (nicht von mir) im WP-Forum, nur jetzt interessiert es mich halt, ob möglich.

06.10.2013 14:13

2 Jörg Kruse

$table ist hier wp_posts, nehme ich an?

Die Verknüpfung geht dann wohl schon über drei JOINS:

$suche = $wpdb->get_results("
    SELECT *
    FROM wp_posts AS p
    LEFT JOIN wp_term_relationships AS tr
    ON p.ID = tr.object_id
    LEFT JOIN wp_term_taxonomy AS tt
    ON tr.term_taxonomy_id = tt.term_taxonomy_id
    LEFT JOIN wp_terms AS t
    ON  tt.term_id = t.term_id
    WHERE p.post_type = 'post'
    AND (
        p.post_title LIKE '%".$gesucht."%'
        OR p.post_content LIKE '%".$gesucht."%'
        OR t.name LIKE '%".$gesucht."%'
    )
");

Muss man schauen, inwieweit die Query noch performant ist

06.10.2013 17:18 | geändert: 06.10.2013 17:20

1 Forenmitglied fand diesen Beitrag gut

3 Horst_M

Jetzt sieht das schon freundlicher aus, ich bedanke mich. Funktioniert eigentlich auch, bis auf eine Kleinigkeit, weil nach t.name nicht mit dem Suchbegriff gesucht wird, sondern nach dem zur term_id gehörenden Namen, der ja t.name ist.

Nun muss ich erst einmal verstehen, was Du da geschrieben hast, weil immer mit AS ein Kürzel zugeordnet wird und ich mit einem JOIN und zwei Tabellen schon nicht klar kam. Führt man die WHERE immer zum Schluss aus? Dann lag wohl ein Fehler mit darin, dass ich mit der begann. Ich denke, da muss ich noch einiges lernen.

06.10.2013 19:33 | geändert: 06.10.2013 19:35

4 Jörg Kruse

Die Kürzel kann man auch weglassen, man muss dann halt die Tabellennamen immer ausschreiben.

Die JOIN Statements schließen sich immer direkt dem FROM Statement an, sind gewissermaßen eine Erweiterung dessen. Andere Statements (WHERE, ODER BY etc.) folgen danach.

Funktioniert eigentlich auch, bis auf eine Kleinigkeit, weil nach t.name nicht mit dem Suchbegriff gesucht wird, sondern nach dem zur term_id gehörenden Namen, der ja t.name ist.

OK, da habe ich nicht genau gelesen:

Nun sollten aber noch die Kategorien angezeigt werden

Die sind dann auch bereits in dem "*" des SELECT Statement enthalten, so wie alle Felder der in dieser Query befragten Tabellen. Vermutlich kann man in der foreach Schleife über ein $detail->name darauf zugreifen

Diese zusätzliche Bedingung kann man dann rausnehmen:

        OR t.name LIKE '%".$gesucht."%'

06.10.2013 22:03 | geändert: 06.10.2013 22:05

5 Horst_M

Zitat von Jörg
Muss man schauen, inwieweit die Query noch performant ist

Funktioniert bisher gut und zumindest in der Testumgebung weist nichts auf ein mögliches Performance-Problem hin. Die beteiligten Tabellen besitzen ja eigentlich nur wenige Datensätze, einzig die wp_posts soll mit der Zeit etwas wachsen.

Stelle mir das bislang so vor, dass diese Abfrage nur einmalig nach einer Suchanfrage erfolgt, da die "Treffer in Kategorien" ja bei einer Blätterfunktion nicht auf allen Blätterseiten neu durchlaufen werden müssen, sondern ab Seite 2 die WP Suchergebnisse genügen und Treffer in "Treffer in Kategorien" nur von Seite 1 übernommen wird.

Zitat von Jörg
Vermutlich kann man in der foreach Schleife über ein $detail->name darauf zugreifen

Diese zusätzliche Bedingung kann man dann rausnehmen:

        OR t.name LIKE '%".$gesucht."%'

Ja, so ist es, habe ich gestern noch bemerkt. Was ich heute noch bemerkte, hatte die statischen Seiten vergessen, so sollte es nun wohl gut sein.

    $tpref = $wpdb->prefix;
    $suche = $wpdb->get_results("
        SELECT *
        FROM ".$tpref."posts AS p
        LEFT JOIN ".$tpref."term_relationships AS tr
        ON p.ID = tr.object_id
        LEFT JOIN ".$tpref."term_taxonomy AS tt
        ON tr.term_taxonomy_id = tt.term_taxonomy_id
        LEFT JOIN ".$tpref."terms AS t
        ON  tt.term_id = t.term_id
        WHERE (p.post_type = 'post' OR p.post_type = 'page')
        AND (
            p.post_title LIKE '%".$gesucht."%'
            OR p.post_content LIKE '%".$gesucht."%'
        )
    ");

Die Ergebnisse sehen stimmig und sauber aus, soweit ich das bisher einschätzen kann.

Danke, so langsam beginne ich auch Verknüpfungen mit JOIN zu begreifen, bis gestern hatte ich immer einen Bogen um Verknüpfungen gemacht, zumal ja meine Scripts bisher eigentlich mit einer Tabelle auskamen.

07.10.2013 12:05

Beitrag schreiben (als Gast)

Die Antwort wird nach der Überprüfung durch einen Moderator freigeschaltet.





[BBCode-Hilfe]