1

我有以下表格

元表

id | recording_id | meta_key | meta_value

记录表

id | recording

recording_idon themeta_table是指向记录表上的记录的外键。

现在我有一个带有元键和值的关联数组$metas$_GET我想要SELECT匹配所有元键和值的记录。我该怎么做?

这就是我到目前为止所拥有的。如何将数组添加到绑定参数中?我在正确的轨道上吗?

我只是无法解决这个问题。

function retrieveRecordingsByMetaData($connection, $config, $metas, $limit)
{
    $where = "";
    for ($i = 0; $i < count($metas); $i++) {
        $where .= "meta_key=? AND meta_value=? AND ";
    }
    $where = preg_replace('/ AND $/', '', $where);

    $sql = "SELECT recording_id 
    FROM $config->meta_table 
    WHERE " . $where . " 
    INNER JOIN $config->recording_table 
    ON $config->meta_table.id=$config->recording_table.id 
    LIMIT ?";

    $stmt = $connection->prepare($sql);

    foreach ($metas as $key => $value) {
        $stmt->bind_param("s", $key);
        $stmt->bind_param("s", $value);
    }
    $stmt->bind_param("i", $limit);

    if (!$stmt->execute()) {
        echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error . " \r\n";
        die();
    }

    $result = $stmt->get_result();
    if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            echo "recording found";
            //$recording = $row["recording"];
            //$hex = bin2hex($recording);
            //echo ("response=recording" . $id . "=" . $hex . "\r\n");
        }
    } else {
        echo "0 results \r\n";
    }
}
4

1 回答 1

1

要仅在 SQL 中编写此查询,您可以编写类似

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子句断言记录具有所有指定的元键和值对。

$where要将其转换为您的 PHP 代码,您需要以类似的方式构建您的子句;我更喜欢使用数组和内爆来避免担心尾随AND等。在构建该子句的同时,我们可以构建以下输入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();
}

可以在此处找到查询形成和参数生成的演示。

于 2019-12-05T03:00:14.763 回答