MySQL zoek query filter op waarde maar geen alle meta_value terug

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Bryan De Baar

Bryan De Baar

24/05/2020 13:46:30
Quote Anchor link
Goedemiddag,

Ik maak gebruik van deze query

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
SELECT *
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON (pm.post_id = p.ID AND pm.meta_key = '_sku')
WHERE p.post_title LIKE '%rad%'
OR IF(pm.meta_value IS NULL, 0, pm.meta_value LIKE '%rad%')


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
    echo $row['post_title'];
    echo $row['meta_value'];
?>


wp_posts
IDpost_title
1radio
2televisie


wp_postmeta
meta_idpost_idmeta_keymeta_value
11price12.50
21_sku5876gh7
31thumb_id56
42price342.50
52_skutv784
62thumb_id78



Met deze query zoek ik in de post_title en in de meta_value kolom als kolom meta_key de waarde _sku bevat.
Zo kan ik zoeken op naam en artikelnummer.

De query zoals hierboven geeft als resultaat
- Radio
- 5876gh7

Maar ik wil ook de price en de thumb_id hebben uit de kolom meta_value.
Als ik het rood gemarkeerde weghaal
LEFT JOIN wp_postmeta pm ON (pm.post_id = p.ID AND pm.meta_key = '_sku') krijg ik alle meta_values terug maar dan word er ook in alle meta_values gezocht wat alleen mag als de meta_key _sku is.

Wat dien ik aan te passen in mijn query?
Gewijzigd op 24/05/2020 13:47:36 door Bryan De Baar
 
PHP hulp

PHP hulp

23/12/2024 17:43:15
 
Adoptive Solution

Adoptive Solution

24/05/2020 14:06:45
 
Thomas van den Heuvel

Thomas van den Heuvel

24/05/2020 14:25:51
Quote Anchor link
Je wilt informatie uit wp_postmeta, dus daar zul je je SELECT op uit moeten voeren.

Je condities komen zowel uit wp_posts alsook wp_postmeta. Specifiek, dit levert (in beide gevallen) bepaalde id's uit de wp_posts tabel op.

Dit levert mogelijk meerdere id's op (als je bijvoorbeeld op "7" zoekt krijg je beide posts terug omdat "7" in beide _sku's voorkomt), dus waarschijnlijk wil je ook sorteren op post_id, en dan op meta_id ofzo.

Het volgende werkt volgens mij:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
SELECT p.ID, p.post_title, m.meta_id, m.meta_key, m.meta_value
FROM wp_posts p
LEFT JOIN wp_postmeta m ON (m.post_id = p.ID)
WHERE EXISTS (SELECT 1 FROM wp_posts WHERE post_title LIKE '%rad%' AND ID = p.ID)
OR EXISTS (SELECT 1 FROM wp_postmeta WHERE meta_key = '_sku' AND meta_value LIKE '%rad%' AND post_id = p.ID)
ORDER BY p.ID, m.meta_id;


Maar dit is weer een vraagstuk over de wp_posts tabel, hier is recent een soortgelijke vraag over gesteld en mogelijk heeft WordPress hier out-of-the-box functionaliteit (interne link) voor.

Voordat je dit soort queries in elkaar loopt te hacken zou je eigenlijk moeten kijken of je dit met standaard WP functionaliteit op kunt lossen.
 
Bryan De Baar

Bryan De Baar

24/05/2020 15:02:18
Quote Anchor link
Hoi Thomas,


Dit ga ik even proberen :-). Hoewel het wel een Wordpress tabel is ail ik deze query buiten Wordpress gebruiken.
Vandaar dat ik niet de standaard wordpress functies gebruik.


Toevoeging op 24/05/2020 16:30:49:

Dit werkt inderdaad Thomas :)

Omdat ik de post_title nu even vaak terug krijg als de meta_value heb ik GROUP BY post_title geprobeerd omdat ik de post_title natuurlijk maar 1x hoef te hebben. Maar dan krijg ik maar 1 record terug.

Kan ik dit het beste oplossen met PHP en controleren of deze al bestaat of kan dit worden aangeven in de query?
 
Adoptive Solution

Adoptive Solution

24/05/2020 16:46:37
Quote Anchor link
Zo los ik het op.
Even de SELECT controleren op juiste WHERE.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

<title>Winkel</title>

<meta name="viewport" content="user-scalable=1, width=device-width, initial-scale=1.0, maximum-scale=2.0, minimum-scale=1.0" />

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

<style>
html {
    font-size: 13px;
    }

div {
    width: 600px;
    padding: 1.000em;
    border: 0.100em solid red;
    margin: 1.000em auto;
    font-family: futura;
    font-size: 1.100em;
    }

table, th, td {
    border: 0.100em solid navy;
    border-collapse: collapse;
    }

table {
    width: 100%;
    }

th {
    text-align: left;
    background-color: #dcdc00;
    }

th, td {
    padding: 0.500em;
    vertical-align: top;
    }

tr:nth-child(odd) {
    background: #dcdcdc;
    }

tr:nth-child(even) {
    background: #dcdcaa;
    }

tr.afspraak {
    background: ivory;
    }

</style>

</head>

<body>

<div>

<?php
include ('config.php');
$query = "SELECT
    p.post_title AS naam,
    GROUP_CONCAT(pm.meta_key   ORDER BY pm.meta_key separator ';') AS sleutel,
    GROUP_CONCAT(pm.meta_value ORDER BY pm.meta_key separator ';') AS waarde
FROM
    wp_posts p
LEFT JOIN
    wp_postmeta pm
ON
    p.id = pm.post_id
WHERE
    p.post_title LIKE '%rad%' OR pm.post_id >= 1
GROUP BY
    pm.post_id;"
;

$result = $db->query( $query );

?>


<table border="1">
    <thead>
        <caption>Winkel</caption>
        <tr>

        <?php
        $velden
= $result->fetch_fields();
        foreach ( $velden as $veld )
        {

        ?>

            <th><?php echo ucfirst( $veld->name ); ?></th>
        <?php
        }
        ?>

        </tr>
    </thead>
    <tbody>

<?php
    while ( $row = $result->fetch_object() )
    {

        echo '<tr><td colspan="3"><pre>' . print_r( $row, TRUE ) . '</pre></td></tr>';
    ?>

        <tr class='afspraak'>
        <td><?php echo $row->naam; ?></td>
        <td>
        <?php
        $sleutels
= explode( ";", $row->sleutel );
        //echo '<pre>' . print_r( $sleutels, TRUE ) . '</pre>';
        foreach ( $sleutels as $sleutel )
        {

            echo $sleutel . '<br />';
        }

        ?>

        </td>
        <td>
        <?php
        $waarden
= explode( ";", $row->waarde );
        //echo '<pre>' . print_r( $waarden, TRUE ) . '</pre>';
        foreach ( $waarden as $waarde )
        {

            echo $waarde . '<br />';
        }

        ?>

        </td>
        </tr>
    <?php
    }?>


    </tbody>
    <tfoot>
        <tr>
            <td colspan="5"></td>
        </tr>
    </tfoot>
</table>

</div>

</body>

</html>
Gewijzigd op 24/05/2020 16:47:01 door Adoptive Solution
 
Jop B

Jop B

24/05/2020 16:48:05
Quote Anchor link
Yes kan met PHP

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
while($row = mysqli_fetch_array($result)){
    if ($row['post_title'] != $current_post_title) {
        echo $row[post_title];
        $current_post_title = $row['post_title'];
    }
}

?>
Gewijzigd op 24/05/2020 17:24:31 door Jop B
 
Thomas van den Heuvel

Thomas van den Heuvel

24/05/2020 17:03:16
Quote Anchor link
Hm, een soortgelijk probleem is de afgelopen maand 2x de revue gepasseerd:
https://www.phphulp.nl/php/forum/topic/groeperen-van-items/103526/
https://www.phphulp.nl/php/forum/topic/div-einde-toevoegen-nadata-alle-elementen-per-category-er-in-staan/103487/

Meerdere manieren om dit op te lossen, bijvoorbeeld:
- bouw eerst een hulparray in PHP-met de query-resultaten (zie tweede thread), of
- houd on-the-fly bij in welke rubriek je zat (eerste thread of zoals @Jop hierboven aangeeft), hierbij moet je dus wel sorteren op deze rubriek.

@Adoptive: alweer eerst een GROUP_CONCAT en dan een explode? :/

Quote:
Kan ik dit het beste oplossen met PHP en controleren of deze al bestaat of kan dit worden aangeven in de query?

Als je de price en thumb_id nodig hebt zoals je in je oorspronkelijke bericht aangeeft zul je deze informatie nog stees op moeten halen. Ik zou dit "gestructureerd" doen (en dit niet op één hoop gooien zodat de betekenis van de informatie min of meer verloren gaat) zodat je later deze data nog (aan de PHP-kant) aan kunt passen zonder de query te veranderen.

Het zou niet nodig moeten zijn dat je informatie die uit de database afkomstig is nog moet bewerken / "uit moet pakken" om deze te kunnen gebruiken. Deze zou direct gebruiksklaar, of op zijn minst "direct leesbaar", moeten zijn.
Gewijzigd op 24/05/2020 17:09:30 door Thomas van den Heuvel
 
Adoptive Solution

Adoptive Solution

24/05/2020 17:13:06
Quote Anchor link
Alles volgens het boekje?
 
Thomas van den Heuvel

Thomas van den Heuvel

24/05/2020 17:29:29
Quote Anchor link
Nou nee voor iets simpels hoeft dat niet per se, maar ik vind het gewoon tegennatuurlijk om voor een bepaalde aanpak te kiezen (GROUP_CONCAT) waar je vervolgens weer (extra) code voor moet schrijven (in de vorm van explode).

Dit is zoiets als een oplossing verzinnen voor een probleem dat je zelf introduceert.

Het werkt verder prima daar niet van, maar ik zou het zo simpelweg niet aanpakken :).
 
Bryan De Baar

Bryan De Baar

25/05/2020 21:48:14
Quote Anchor link
@thomas,


Ik zou dan een array willen aanmaken en die dan terug sturen en met jQuery de opmaak willen maken.
Dat word dan een array gevuld met arrays?
Hoe kan ik dan per post_title met bijhorende meta_value's een array in de array maken?

Stel dat ik zoek op 7 en ik krijg beide terug:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$sendback
= array(
    array(
        'id'            => '1',
        'post_title'     => 'radio',
        'price'            => '12.50',
        'sku'            => '5876gh7',
        'thumb_id'        => '56'
    ),
    array(
        'id'            => '2',
        'post_title'     => 'televisie',
        'price'            => '342.50',
        'sku'            => 'tv784',
        'thumb_id'        => '78'
    ),
)

?>
 
Adoptive Solution

Adoptive Solution

25/05/2020 21:57:32
Quote Anchor link
Zo

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
while ( $row = $result->fetch_object() )
{
    $sendback[] = $row;
}
 
Bryan De Baar

Bryan De Baar

25/05/2020 22:16:51
Quote Anchor link
@adoptive Solutions,


Deze had ik al geprobeerd opzich krijg ik het dan inderdaad in een array maar dan zit ik weer met die dubbele post_title.
 
Thomas van den Heuvel

Thomas van den Heuvel

25/05/2020 23:48:34
Quote Anchor link
Je kunt de subarrays aan het wp_posts ID hangen.

Als je mijn aanpak gebruikte met de "dubbele data" in de records, kun je dit heel eenvoudig doen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$data
= array();
$query = '...'; // mijn eerdere query
$res = $db->query($query);
while ($row = $res->fetch_assoc()) {
    // indien het subarray nog niet bestaat, maak deze aan
    if (false === isset($data[$row['ID']])) {
        // kopieer wp_posts specifieke data eenmalig bij creatie subarray
        $data[$row['ID']] = array(
            'id' => $row['ID'],
            'post_title' => $row['post_title'],
        );
    }

    // nu kun je zonder zorgen alle overige key-value paren aan dit subarray toevoegen
    // de isset-controle garandeert immers dat dit subarray bestaat

    $data[$row['ID']][$row['meta_key']] = $row['meta_value'];
}

?>
Gewijzigd op 26/05/2020 13:59:30 door Thomas van den Heuvel
 
Bryan De Baar

Bryan De Baar

02/06/2020 23:21:34
Quote Anchor link
Hi Thomas,


Deze code werkt inderdaad prima. Echter heb ik nog een vraag.

In de kolom meta_key word per artikel nog een record aangemaakt met manage_stock en stock met in de meta_value de waarde yes voor manage_stock en een aantal voor stock.

meta_idpost_idmeta_keymeta_value
11price12.50
21_sku5876gh7
31thumb_id56
41manage_stockyes
51stock5
62price342.50
72_skutv784
82thumb_id78
92stock10
102manage_Stock yes


Als de record meta_key -> manage_stock meta_value-> yes is dan voeg de record meta_key -> stock de waarde van meta_value toe.
Omdat het systeem de ene keer de record manage_stock boven de record stock zet en de ene keer andersom dus de stock boven de manage stock zet kan ik dit niet oplossen met een if statement in de loop zoals ik onderstaand heb geprobeerd.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
while($row = mysqli_fetch_assoc($result)){
    if (false === isset($data[$row['ID']])) {
        $data[$row['ID']] = array(
            'id'             => $row['ID'],
            'post_title'     => $row['post_title'],
            'price'            => '-',
            'stock'            => 'geen voorraad'
        );
        
    }

    
    if($row['meta_key'] == '_price' ){
        if($row['meta_value'] !== ''){    
               $data[$row['ID']]['price']     = $row['meta_value'];
           }
else{
               $data[$row['ID']]['price'] = '-';
           }
    }

    
    if($row['meta_key'] == '_stock_status' ){
        $data[$row['ID']]['stock_status'] = $row['meta_value'];
    }

    
     if($row['meta_key'] == '_manage_stock' ){
         if($row['meta_value'] == 'yes'){
             if($row['meta_key'] == '_stock' ){
                 $data[$row['ID']]['stock'] = $row['meta_value'];
             }
         }    
     }
}

?>


Moet ik dan nog een andere hulp array maken of nog een losse query om dit voor elkaar te krijgen?
Gewijzigd op 02/06/2020 23:22:08 door Bryan De Baar
 
Thomas van den Heuvel

Thomas van den Heuvel

03/06/2020 00:06:34
Quote Anchor link
Nee? Intruceer gewoon twee velden (manage_stock (default false), stock (default 0)) en vul beide in als de records voorbij komen. Voeg vervolgens wat logica toe om de juiste informatie weer te geven, op grond van de uiteindelijke waarden van manage_stock en stock.

Overigens, dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
if($row['meta_key'] == '_price' ){
    if($row['meta_value'] !== ''){    
        $data[$row['ID']]['price']     = $row['meta_value'];
    }
else{
        $data[$row['ID']]['price'] = '-';
    }
}

?>

Is toch niet nodig? Overschrijf de default alleen als dat nodig is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
if ($row['meta_key'] == '_price' && $row['meta_value'] !== '') {
    $data[$row['ID']]['price'] = $row['meta_value'];
}

?>

Houd het simpel.
Gewijzigd op 03/06/2020 00:09:32 door Thomas van den Heuvel
 
Bryan De Baar

Bryan De Baar

03/06/2020 00:59:43
Quote Anchor link
Duidelijk Thomas,


Maar als ik de manage_stock default op false heb staan en de record met stock word eerder geladen dan moet ik deze dan ergens in een variable zetten en als de manage_stock record is gelezen en yes is toevoegen aan array?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
if($row['meta_key'] == '_manage_stock' ){
         if($row['meta_value'] == 'yes'){
             if($row['meta_key'] == '_stock' ){
                 $data[$row['ID']]['stock'] = $row['meta_value'];
             }
         }    
     }

?>

Deze code zal van de bovenstaande table alleen werken op post_id 1 en niet op post_id 2
 
Thomas van den Heuvel

Thomas van den Heuvel

03/06/2020 01:57:46
Quote Anchor link
Bryan De Baar op 03/06/2020 00:59:43:
Duidelijk Thomas,

Nou ja, niet helemaal dus :p.

Bryan De Baar op 03/06/2020 00:59:43:
Maar als ik de manage_stock default op false heb staan en de record met stock word eerder geladen dan moet ik deze dan ergens in een variable zetten en als de manage_stock record is gelezen en yes is toevoegen aan array?

Dat is precies wat ik in mijn vorige reactie voorstelde. Sla in plaats van "yes" simpelweg true op.

Als daar dan het moment is om stock weer te geven inspecteer je eerste manage_stock:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$stock
= $whatever[$productId]['manage_stock'] ? $whatever[$productId]['stock'] : 'niet op voorraad';
?>

Of wat voor logica van toepassing is, ik weet niet onder welke voorwaarden je wat wilt weergeven.

Je zou dit alles ook generieker kunnen maken door een whitelist op te stellen voor de meta_keys waarin je geinteresseerd bent, en hier vervolgens ook "vertaalregels" aan kunnen hangen om de informatie nog wat te ordenen voordat je dit intern in een hulparray opslaat.
Gewijzigd op 03/06/2020 02:02:12 door Thomas van den Heuvel
 
Jop B

Jop B

03/06/2020 20:25:10
Quote Anchor link
Hi Bryan,


Als je nu eerst een variabel aanmaakt voor _stock en _manage_stock en vervolgens een if statement toepast op deze?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
while($row = mysqli_fetch_assoc($result)){    
    if (false === isset($data[$row['ID']])) {
//we zetten manage_stock (ms_on) op no als defautl
        $ms_on = 'no';
        $data[$row['ID']] = array(
            'id'             => $row['ID'],
            'post_title'     => $row['post_title'],
            'price'            => '-',
//stock zetten we op 0 als default
            'stock'            => '0',
        );    
    }

        
        if ($row['meta_key'] == '_price' && $row['meta_value'] !== '') {
            $data[$row['ID']]['price'] = $row['meta_value'];
        }

        
//we slaan de meta_value van stock op in een variabel
        if ($row['meta_key'] == '_stock' && $row['meta_value'] !== '') {
            $stock = $row['meta_value'];
        }

//we slaan de meta_value van _manage_stock op in een variable
        if ($row['meta_key'] == '_manage_stock' && $row['meta_value'] !== '') {
            $ms_on = $row['meta_value'];
        }

//omdat beide variables nu gevuld zijn door de default of zijn overschreven door je resultaten kunnen we nu een if statement maken en dan stock in de array zetten    
        if($ms_on == 'yes'){
            $data[$row['ID']]['stock'] = $stock;
        }    
}

?>
 
Thomas van den Heuvel

Thomas van den Heuvel

03/06/2020 21:18:36
Quote Anchor link
Of je regelt dit gewoon ergens anders? Code wordt onwijs wollig op deze manier.

Gebruik (ook) op zijn minst Boolse waarden in plaats van een variabele met waarden als 'yes' en 'no' alsjeblieft, dit type bestaat niet voor niets...
 
Bryan De Baar

Bryan De Baar

03/06/2020 21:33:12
Quote Anchor link
Bedankt voor jullie reacties.

@Jop dit werkt inderdaad :)

@Thomas helaas hanteert dit systeem de waarde yes ipv true. Ik ben dus gebonden aan yes.
 
Thomas van den Heuvel

Thomas van den Heuvel

03/06/2020 21:37:23
Quote Anchor link
Ik bedoel de variabele die je zelf definieert. Er is geen enkele reden om (in je interne administratie) die stompzinnige waarden aan te houden.
Gewijzigd op 03/06/2020 21:37:47 door Thomas van den Heuvel
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.