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



<?php
	echo $row['post_title'];
	echo $row['meta_value'];
?>


wp_posts
[table]
[tr][td]ID[/td][td]post_title[/td][/tr]
[tr][td]1[/td][td]radio[/td][/tr]
[tr][td]2[/td][td]televisie[/td][/tr]
[/table]

wp_postmeta
[table]
[tr][td]meta_id[/td][td]post_id[/td][td]meta_key[/td][td]meta_value[/td][/tr]
[tr][td]1[/td][td]1[/td][td]price[/td][td]12.50[/td][/tr]
[tr][td]2[/td][td]1[/td][td]_sku[/td][td]5876gh7[/td][/tr]
[tr][td]3[/td][td]1[/td][td]thumb_id[/td][td]56[/td][/tr]
[tr][td]4[/td][td]2[/td][td]price[/td][td]342.50[/td][/tr]
[tr][td]5[/td][td]2[/td][td]_sku[/td][td]tv784[/td][/tr]
[tr][td]6[/td][td]2[/td][td]thumb_id[/td][td]78[/td][/tr]
[/table]


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.

Wat dien ik aan te passen in mijn query?
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:
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.
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.


[size=xsmall]Toevoeging op 24/05/2020 16:30:49:[/size]

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?
Zo los ik het op.
Even de SELECT controleren op juiste WHERE.

 <!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>
Yes kan met PHP


<?php
while($row = mysqli_fetch_array($result)){
    if ($row['post_title'] != $current_post_title) {
        echo $row[post_title];
        $current_post_title = $row['post_title'];
    }
}
?>
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? :/

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.
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 :).
@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:

<?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'
	),
)
?>
Zo

while ( $row = $result->fetch_object() )
{
	$sendback[] = $row;
}

Reageren