MySQL zoek query filter op waarde maar geen alle meta_value terug
Door
Bryan De Baar
op 24-05-2020 13:46
gewijzigd op 24-05-2020 13:47
3.686 views
Goedemiddag,
Ik maak gebruik van deze query
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%')
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 [color="#ff0000"]([/color]pm.post_id = p.ID [color="#ff0000"]AND pm.meta_key = '_sku')[/color] 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.
Als je mijn aanpak gebruikte met de "dubbele data" in de records, kun je dit heel eenvoudig doen:
<?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'];
}
?>
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.
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.
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.
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?
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:
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.
Als je nu eerst een variabel aanmaakt voor _stock en _manage_stock en vervolgens een if statement toepast op deze?
<?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;
}
}
?>