Untuk menulis kueri ini hanya dalam SQL, Anda akan menulis sesuatu seperti
SELECT r.id
FROM recording r
JOIN meta m ON m.recording_id = r.id
AND (m.meta_key = 'key1' AND m.meta_value = 'value1'
OR m.meta_key = 'key2' AND m.meta_value = 'value2'
OR m.meta_key = 'key3' AND m.meta_value = 'value3'
...)
GROUP BY r.id
HAVING COUNT(*) = <count of all key/value pairs>
LIMIT 10
HAVING
klausa adalah apa yang menegaskan bahwa rekaman memiliki semua kunci meta dan pasangan nilai yang ditentukan.
Untuk menerjemahkannya ke dalam kode PHP, Anda perlu membangun $where
klausa dengan cara yang sama; Saya lebih suka menggunakan array dan meledak untuk menghemat kekhawatiran tentang tertinggal AND
dan sejenisnya. Pada saat yang sama saat kita membangun klausa itu, kita dapat membangun input ke bind_param
:
$join = array();
$params = array();
$types = '';
foreach ($metas as $key => $value) {
$join[] = 'm.meta_key=? AND m.meta_value=?';
$params[] = $key;
$params[] = $value;
$types .= 'ss';
}
// add the parameter for the `HAVING` check
$params[] = count($metas);
$types .= 'i';
// add the limit
$params[] = $limit;
$types .= 'i';
// make the query string
$sql = "SELECT recording_id
FROM {$config->recording_table} r
JOIN {$config->meta_table} m ON m.recording_id = r.id
AND (" . implode(' OR ', $join) . ")
GROUP BY r.id
HAVING COUNT(*) = ?
LIMIT ?";
$stmt = $connection->prepare($sql);
if (!$stmt) {
echo "Prepare failed: " . $conn->error . "\n";
die();
}
$stmt->bind_param($types, ...$params);
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error . " \r\n";
die();
}
Demo pembentukan kueri dan pembuatan parameter dapat ditemukan di sini .