sql >> Database teknologi >  >> RDS >> Mysql

Vælg en optagelse baseret på metaen

For at skrive denne forespørgsel kun i SQL, ville du skrive noget i stil med

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 klausul er det, der hævder, at en optagelse har alle de angivne meta-nøgle- og værdipar.

For at oversætte det til din PHP-kode, skal du opbygge din $where klausul på lignende måde; Jeg foretrækker at bruge et array og implodering for at spare på at bekymre mig om efterfølgende AND og lignende. Samtidig med at vi bygger den klausul, kan vi bygge input til 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();
}

En demo af forespørgselsdannelsen og paramsgenereringen kan findes her .




  1. Skal jeg gemme landenavne i MySQL for hver bruger?

  2. Indsæt data fra SQL Server til MySql ved hjælp af Trigger

  3. Brug SET TEXTSIZE til at begrænse de data, der returneres for hver række i SQL Server

  4. Sådan flyttes en model mellem to Django-apps (Django 1.7)