MySQL AND nem működik megfelelően

MySQL AND nem működik megfelelően
2019-03-05T10:44:30+01:00
2019-03-05T16:03:24+01:00
2022-10-15T21:30:25+02:00
GalgLev
Az alábbi kód nem működik, ha 1-nél több search term-et tartalmaz a get_query_var( 'search_terms' ) tömb. Nem igen erősségem az SQL, több mint egy órája próbálom megtalálni a hibát, de nem megy:

function custom_search_where_filter( $where ) { global $wpdb, $wp_query; if( !is_search() ) return $where; $where .= " OR ("; $i = 0; foreach( get_query_var( 'search_terms' ) as $search_term ) { #get_query_var( 'search_terms' ) <- mindig tömböt ad vissza $i++; if( $i > 1 ) $where .= " AND "; #ez nem működik... Ha OR-ra váltom, az OR-nak megfelelően működök, 1-nél több term-el is... $where .= "(t.name LIKE '%" . $search_term . "%' OR t.slug LIKE '%" . $search_term . "%')"; } $where .= " AND " . $wpdb->posts . ".post_status = 'publish')"; return $where; } add_filter( 'posts_where', 'custom_search_where_filter' );
*Tehát a filter tökéletesen működik 1 db search term-el (tehát pl ha a keresés:[zöld] kilistázza az összes postot aminek a címében vagy valamelyik tagjának a nevében vagy slug-jában talál egyezést).
*Nem működik több-el, amennyiben azok közül az egyik csak egy tag nevében vagy slugjában található meg ([zöld gaz]-ra nincs találat abban az esetben sem, ha biztosan van zöld és gaz nevű tagokkal cimkézett post).
*OR-al tökéletesen működik (ez fontos, mert ebből látszik, hogy a hiba biztosan a fenti filterben van, és nem máshol... (tehát OR esetén a [zöld gaz]-ra kidobja az összes postot aminek a címében vagy valamelyik tagjának a nevében vagy slugjában szerepel a zöld vagy a gaz. )).

Elnézést ha szájbarágós volt, de próbálom kizárni a felesleges köröket.

Amit még próbáltam (van, hogy néhány plusz zárójel segít (powershellben pl kötelező tagolni mindent, php-ben ritkán kell, viszont ezesetben sajnos) szintén nem működik):

foreach( get_query_var( 'search_terms' ) as $search_term ) { $i++; $where .= $i > 1 ? " AND " : "("; $where .= "(t.name LIKE '%" . $search_term . "%' OR t.slug LIKE '%" . $search_term . "%')"; } $where .= ") AND " . $wpdb->posts . ".post_status = 'publish')";
Valakinek van ötlete mi lehet a hiba az AND-el?
Mutasd a teljes hozzászólást!

  • Első körben, mondjuk kiprintelhetnéd (majd idézhetnéd ide) azt a $where-t, hogy kiderüljön, milyen SQL lesz a vége!
    Mutasd a teljes hozzászólást!
  • AND (((wp_75_posts.post_title LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_excerpt LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_content LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}')) AND ((wp_75_posts.post_title LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_excerpt LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_content LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}'))) AND wp_75_posts.post_type IN ('post', 'rebloggedposts') AND (wp_75_posts.post_status = 'publish' OR wp_75_posts.post_status = 'private') OR ((t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND wp_75_posts.post_status = 'publish')

    Ez eddig eszembe se jutott... viszont a hibát továbbra sem találom...
    Mutasd a teljes hozzászólást!
  • Megpróbáltam - számomra - olvashatóvá tenni a kifejezést:

    AND ( ( (wp_75_posts.post_title LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_excerpt LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_content LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}zold{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') ) AND ( (wp_75_posts.post_title LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_excerpt LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') OR (wp_75_posts.post_content LIKE '{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}gaz{6468d322a895f909124b43768404db490f054ba603dee8bd3102c2691b09a6c0}') ) ) AND wp_75_posts.post_type IN ('post', 'rebloggedposts') AND (wp_75_posts.post_status = 'publish' OR wp_75_posts.post_status = 'private') OR ( (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND wp_75_posts.post_status = 'publish' )

    Tudom ez nem segítség, de ez alapján szerintem a zárójelezés nem teljesen ok. Darabszámra igen, de logikailag valami mégsem kerek.
    Mutasd a teljes hozzászólást!
  • A kérdésben szereplő második verzió így néz ki (tagolva):

    ... AND ( wp_75_posts.post_status = 'publish' OR wp_75_posts.post_status = 'private' ) OR ( ( ( t.name LIKE '%zold%' OR t.slug LIKE '%zold%' ) AND ( t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%' ) ) AND wp_75_posts.post_status = 'publish' )
    Mutasd a teljes hozzászólást!
  • Ha jól látom, akkor a kódod ezt a részt rakja bele a WHERE-be:

    OR ( (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND wp_75_posts.post_status = 'publish' )

    Nem lehet az, hogy az utolsó része kavar be, és nincs olyan 'publish' státuszú rekord, ami megfelelne a többi feltételednek?
    Mutasd a teljes hozzászólást!
  • Kivettem, tehát ebben az esetben ez lesz az, amivel a filter bővíti a where-t:

    OR ( (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') )

    De továbbra sem találja meg a postot (100%, hogy van megfelelő post (és publish... és ha az AND helyett OR-t használok meg is találja (persze abban az esetben sok másikkal együtt, emelyek vagy csak az egyiket, vagy csak a másikat tartalmazzák))! Hihetetlen, hogy nem találom a hibát...)
    Mutasd a teljes hozzászólást!
  • Érdemes lenne megnézni a többi feltételt is, amiket nem a te filtered rak bele!

    Más:

    Próbálj egy direkt lekérdezést futtatni WP-t kihagyva (pl. valami sql adminban, vagy parancssor):

    SELECT * FROM {nem_tudom_mi_a_tábla_neve} t WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%')
    A tábla nevét értelemszerűen írd be!
    Lesz eredmény?
    Mutasd a teljes hozzászólást!
  • NEm így a jobb?

    OR
        (
            (t.name LIKE '%zold%' OR t.name LIKE '%gaz%')
        AND
            (t.slag LIKE '%zold%' OR t.slug LIKE '%gaz%')

    Mert ahogy te írtad, úgy a t.name zold AND gaz kellene legyen egyszerre, nem?
    Mutasd a teljes hozzászólást!
  • Nem, amit ő írt az kb. ez:
    a kettő közül (name, slug) legalább az egyik tartalmazza a 'zold'-et, és a kettő közül legalább az egyik tartalmazza a 'gaz'-t.
    Mutasd a teljes hozzászólást!
  • Nem találok megoldást, szóval egyelőre az OR-ral fogom használni... egyébként valószínű, hogy a posts_where filter kavar be valamit, ugyanis tegnap találtam egy másik core bug-ot vele kapcsolatban: a filterrel kilistázott postok oldalain (tehát jelen esetben a search.php által generáltakon) nem működnek bizonyos függvények a have_posts() loopon belül, konkretizálva az url_to_postid() behal és a loop első postjának id-jét dobálja vissza a következő elemeknél is, tehát emiatt a get_page_by_path()-ot kell használni, ami tökéletesen működik vele (most nem szánok időt rá, hogy kikeressem a két függvény közti, egyikben hibát okozó különbséget, de mindenesetre érdekes idegesítő... ).
    Mutasd a teljes hozzászólást!
  • Lefuttattad a lekérdezést, amit írtam?
    Mutasd a teljes hozzászólást!
  • Nah, nekifutottam mégegyszer (mert 0 SQL tudással elsőre durván esélytelennek tűnt...)
    Tehát a következő lekérdezéssel kapok 6 postot:

    SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish'

    10-et ha csak ezt a sort használom a kettő közül:

    WHERE (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%')

    16-ot, ha OR-ral mindkettőt (ami már kiéget, mert csak 15-öt szabadna találnia, ugyanis biztosan van 1 közös...):

    WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') OR (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%')

    és 0 post a következőre:

    WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%')

    100%, hogy van 1 közös, mert pont azért tesztelem így... pontosabban, sem gaz sem zold tag nincs a tesztelt site-on, de több 100%-osan létező keresztmetszetet is próbálok egyfolytában, egyikkel sem működik... Tippem sincs mi a baja, de mostmár biztos, hogy nem fogok tudni elaludni tőle...x
    Mutasd a teljes hozzászólást!
  • Mutass egy konkrét t rekordot (a name és a slug mezőket mindenképp), aminek tutira az eredmények között kellene lennie!

    Nincs valami dummy adatbázisod, amit nyilvánossá tehetsz (és persze amin reprodukálható a probléma)?
    Mutasd a teljes hozzászólást!
  • Ha nincs dummy, nem lesz este neki durmy! 
    Mutasd a teljes hozzászólást!
  • sajnos olyanom nincs, de: a terms ($wpdb->terms) táblán belül vannak indexek[name, primary, slug] és oszlopok[name, slug, term_group, term_id]... A name és slug oszlopok típusa varchar(200) az illesztésük pedig utf8mb4_unicode_ci ... Az indexek típusa BTREE, NEM egyediek és NEM csomagoltak, illesztésük A.

    Az a legérhetetlenebb számomra, hogy külön-külön mindekettőből megtalálja a kérdéses postokat, OR-ral is megtalálja mindet, de ha AND-et használok a queryben, behal --> Azóta észrevettem mégvalamit: amennyiben AND-et használok a kérdéses résznél és nem OR-t, egy bizonyos kombinációra kidob egy darab postot, aminek az url-je mindkét kulcsszót tartalmazza... Ezt a postot OR vagy egyedi kulcsszavas keresésre is kidobja (bármelyikre a kettő közül)... Vagyis olyan, mintha attól az AND-től a teljes filter leállna -> azért találja meg azt az egy postot, mert azt a filter nélkül is bedobja az URL-es egyezés miatt...

    Tehát minden arra mutat, hogy azzal az egy darab AND-el nem stimmel valami...
    Mutasd a teljes hozzászólást!
  • Nem mutatod a teljes lekérdezést, ezért csak ötletelek:

    Azt mondod, hogy erre

    SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish'
    6 postot hoz.

    Erre

    SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish'
    viszont 10-et kapsz eredményül.

    A harmadik esetben

    SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') OR (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish'
    16-ot.

    Kérdés: A harmadik kódot ebben a formában írod be? Így adta vissza a 16-ot, vagy megfelelően zárójelezve, vagyis így:

    SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE ((t.name LIKE '%zold%' OR t.slug LIKE '%zold%') OR (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%')) AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish'
    Mutasd a teljes hozzászólást!
  • Mindkét esetben 16-ot ad. (Próbáltam már mindenféle zárójelezést, de nem változtat az eredményen ... a biztonság kedvéért lefuttattam most ezt is, amit írtál, plusz azóta egy ilyet is kipróbáltam:

    WHERE (t.name LIKE '%zold%' AND t.name LIKE '%gaz%')
    szintén 0...

    (mégegyszer hangsúlyzom, egyfolytában több féle kombinációt próbálgatok, olyanokat, amiknek mind a slugja mind a name értéke biztosan tartalmazza mindkét kulcsszót... és ha az AND-et OR-ra cserélem meg is találja az összes postot)

    Egyébként a teljes lekérdezés:

    global $wpdb; $SQL = " SELECT " . $wpdb->posts . ".* FROM " . $wpdb->posts . " LEFT JOIN " . $wpdb->term_relationships . " tr ON " . $wpdb->posts . ".ID = tr.object_id INNER JOIN " . $wpdb->term_taxonomy . " tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN " . $wpdb->terms . " t ON t.term_id = tt.term_id WHERE (t.name LIKE '%zold%' OR t.slug LIKE '%zold%') AND (t.name LIKE '%gaz%' OR t.slug LIKE '%gaz%') AND " . $wpdb->posts . ".post_type = 'post' AND " . $wpdb->posts . ".post_status = 'publish' "; $qposts = $wpdb->get_results( $SQL, OBJECT ); echo count( $qposts );
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd