PHP - использовать массив в запросе MySQL - PullRequest
0 голосов
/ 18 ноября 2018

PHP новичок здесь.Вот пример моей таблицы в базе данных MySQL, из которой я извлекаю данные.

id  classA    classB     value
------------------------------
1   A         A          1
2   A         B          5   
3   A         C          2  
4   B         A          1
5   B         B          5   
6   B         C          1  
7   C         A          8
8   C         B          5   
9   C         C          7  

Пользователь вводит список категорий классов (A, B, C и т. Д.), И мой код будет возвращать значения из каждой комбинации этих пар (например, [A, A], [A, B], [A, C] ... и т. Д.).Я могу легко добиться этого, используя следующий скрипт, где $array - это список ввода (например, [A, B, C]):

<?php
    // Mehtod 1 - slow
    for($i = 0; $i < count($arr); $i++){
        for ($j = 0; $j < count($arr); $j++){
            $sql = "SELECT value FROM data_table WHERE '$arr[$i]'=classA AND '$arr[$j]'=classB LIMIT 1";

            $value = mysqli_query($con,$sql);
            $value = mysqli_fetch_array($corr)[0];

            $results[] = array('classA' => $arr[$i], 'classB' => $arr[$j], 'value' =>  $value);
        }
    }
?>

Однако, это довольно медленно, потому что mysqli_query()внутри для цикла.Вместо этого я бы предпочел сделать запрос в один вызов.Я попробовал следующее без удачи ..

<?php
    // Mehtod 2 - fast
    for($i = 0; $i < count($arr); $i++){
        for ($j = 0; $j < count($arr); $j++){
            // make array of class combinations
            $query_array[] = array('classA' => $arr[$i], 'classB' => $arr[$j]);
        }
    }
    // get arrays of pairs to request
    $match1 = array_column($query_array, 'classA');
    $match2 = array_column($query_array, 'classB');

    $sql = "SELECT classA, classB, value FROM data_table WHERE classA IN '$match1' AND classB IN '$match2'";

    $results = mysqli_query($con,$sql);
    $results = mysqli_fetch_array($results);
?>

Могу ли я сделать такой запрос с помощью одного запроса?Я немного застрял.Приветствия.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Пользователь вводит список категорий классов (A, B, C и т. Д.)

  • Итак, вы находитесь на правильном пути в использовании оператора IN, однако вы не можете напрямую прикрепить $match1 и $match2 в своем запросе SQL, поскольку оба они все еще являются массивами.
  • Вам нужно будет преобразовать их в разделенные запятыми строки и добавить одинарную кавычку в каждую строку, поскольку ваши classA и classB являются строковыми столбцами в вашей таблице БД.

Код:

<?php


$match1 = array('A','B');
$match2 = array('A','B');

$match1_values = implode(",",array_map("addQuotes",$match1));
$match2_values = implode(",",array_map("addQuotes",$match2));

$sql = "SELECT classA, classB, value FROM data_table WHERE classA IN ($match1_values) AND classB IN ($match2_values)";

echo $sql;

function addQuotes($each_class_value){
    return "'".$each_class_value."'";
}

Обновление:

Вы можете заменить

for($i = 0; $i < count($arr); $i++){
        for ($j = 0; $j < count($arr); $j++){
            // make array of class combinations
            $query_array[] = array('classA' => $arr[$i], 'classB' => $arr[$j]);
        }
    }
    // get arrays of pairs to request
    $match1 = array_column($query_array, 'classA');
    $match2 = array_column($query_array, 'classB');

с

<?php

$match_values = implode(",",array_map("addQuotes",$arr));

$sql = "SELECT classA, classB, value FROM data_table WHERE classA IN ($match_values) AND classB IN ($match_values)";

echo $sql;

function addQuotes($each_class_value){
    return "'".$each_class_value."'";
}
0 голосов
/ 18 ноября 2018

Поскольку вам нужны все возможные комбинации, вам не нужно создавать комбинации внутри PHP, а затем использовать их в запросе.

Я бы предпочел сделать следующее:

SELECT classA, classB, value 
FROM data_table
WHERE classA IN ('A', 'B', 'C') AND 
      classB IN ('A', 'B', 'C')

Это будет учитывать все комбинации.Это будет эквивалентно:

SELECT classA, classB, value 
FROM data_table
WHERE (classA = 'A' AND classB = 'A') OR
      (classA = 'A' AND classB = 'B') OR
      (classA = 'A' AND classB = 'C') OR
      (classA = 'B' AND classB = 'A') OR
      (classA = 'B' AND classB = 'B') OR
      (classA = 'B' AND classB = 'C') OR
      (classA = 'C' AND classB = 'A') OR
      (classA = 'C' AND classB = 'B') OR
      (classA = 'C' AND classB = 'C')

В этом случае код PHP будет выглядеть следующим образом:

<?php
    // Method 3 - possibly fastest and neater code

    // get comma separated values to match against
    $match_string = "('" . implode("','", $arr) . "')";

    $sql = "SELECT classA, classB, value 
             FROM data_table 
             WHERE classA IN " . $match_string . " AND 
                   classB IN " . $match_string;

    $results = mysqli_query($con,$sql);
    $results = mysqli_fetch_array($results);
?>

Наиболее важно , чтобы избежать против SQL-инъекция связанных атак, вы должны использовать Подготовленные заявления

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...