MySQL / PHP / PDO + Как получить строку для каждой (повторяющейся) записи в IN ()? - PullRequest
0 голосов
/ 22 мая 2018

Язык: PHP

БД: MySQL

Насколько я понимаю, если у вас есть повторяющиеся записи в предложении IN () ... они будут пропущены ... Мне нужен возврат /строка для каждого элемента в предложении IN () .. независимо от того, являются ли они дублирующими или нет.

Из прочтения ... Я считаю, что [self] JOIN () - это подход / решение, которое я ищу.но я не понимаю, как сделать это JOIN на той же таблице?.. особенно с запросом, который я уже имею ниже.(это работает так, как мне нужно ... ожидать, что не будет возвращена строка для повторяющихся записей в предложении IN ())

Однако .. Я также читал о EXISTS () также ... возможно,лучший подход?(Я не ищу скорость здесь .. Я ищу рабочее решение)

У меня есть пример rextexter для отображения той же таблицы .. (однако этот запрос работает на rextester, но нереальный мир или WAMP..etc)

http://rextester.com/SZRIAN96972

Так что мне не ясно, действительно ли это сам запрос?(я читал, что это будет проблемой, так как dups будет пропущен в предложении IN ()) ... потому что он "работает" в WAMP и REXTESTER ...

Так что, возможно, это часть операций PDO?Может быть, что-то происходит при передаче массива в функцию execute ()?

Фрагмент PDO:

$qMarks = str_repeat('?,', count($brandlist) - 1) . '?'; //create '?' mark placeholders for query, remove last comma and replace with '?'
//preserve IN() order
$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN ($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";             
$displayList_stmt = $conn->prepare($displayList_sql);
$displayList_stmt->execute($brandlist);//make note of passing in array as param to execute() call

Пример массива $ brandList, передаваемого в: (с dups)

Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW'

Итак, на данный момент ... Мне не ясно, является ли предложение IN () проблемой?Или, если что-то делается при передаче массива в команду execute ()?Что-то убирает / пропускает дубликат (ы) в предложении IN ()?Как я могу избежать этого?Я надеялся, что это было какое-то самостоятельное соединение ... но все примеры, которые я видел, имели жестко закодированные значения (которых не может быть) ... и затем повторяющиеся записи, расположенные в первоначальном предложении IN (), использовались во втором запросе или что-то вроде этого.(Я довольно внимательно следил, так как не мог понять, как это применимо к моей ситуации)

вот краткий дамп рабочего примера, который я выполнял при локальной установке WAMP: (нужен собственный файл подключения для подключения)

require_once('../db_wamp_pdo.php');
$tablename = 'xxx';

//hard coded list for testing
$brandList_og = array('Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg');

function get_displayList($tablename, $conn, $brandlist){    
    $rowcount = 0;
    if($brandlist != '' && count($brandlist) > 0){
        $qMarks = str_repeat('?,', count($brandlist) - 1) . '?'; //create '?' mark placeholders for query, remove last comma and replace with '?'       

        //$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN('Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg') ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg')";    

        $displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";  

        //$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) FIND_IN_SET($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";   
        //$displayList_sql = "SELECT * FROM $tablename WHERE EXISTS(SELECT CONCAT(brandname, ' ', dosage)) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";             

        $displayList_stmt = $conn->prepare($displayList_sql);
        $displayList_stmt->execute($brandlist);//make note of passing in array as param to execute() call
        $displayList_stmt->setFetchMode(PDO::FETCH_ASSOC);
        $_displayList = $displayList_stmt->fetchAll(); //returns multi-dimensional array (and correct count)
        $colcount = $displayList_stmt->columnCount();
        $rowcount = $displayList_stmt->rowCount(); 
    }   

    if($rowcount <= 0){
        //nothing returned
    }else{  
        return $_displayList;
    }       
}
$my_displayList = get_displayList($tablename, $conn, array_values(array_filter($brandList_og)));//array_filter() added to get count of only non empty indexes

echo 'BRAND LIST: <br>';
echo var_dump($my_displayList);
echo '<br>';

Я выводил текст отладки по пути ... и с "массивом" все в порядке, пока он не возвращается из запроса ..

Так что это либо IN ()предложение (моя текущая теория), и мне нужна помощь, как-то добавить самостоятельное соединение к этому динамическому запросу?Или (менее правдоподобно) при передаче массива в строку execute () .. все анализируется / удаляется?

1 Ответ

0 голосов
/ 22 мая 2018

Дублирования в предложении in() на самом деле не пропускаются в том смысле, что вы используете слово.Дублированное поле действительно пропускается, но это не имеет значения, поскольку операторы IN() оцениваются как оператор OR.

Например:

select * from table
where table.thing in ('a', 'b')

оценивается как

select * from table
where 
   table.thing    = 'a'
   or table.thing = 'b'

Если мы добавим еще один 'a' к этому оператору IN(), он будет "проигнорирован", поскольку исходное значение 'a' уже соответствует первому.Иметь оптимизатор, записывающий его снова, было бы бессмысленно.

...