Как мне отфильтровать массив php с таблицей MySQL?

Скажем, у меня есть массив строк в массиве php с именем $ foo с несколькими сотнями записей, и у меня есть таблица MySQL «people», в которой есть поле с именем «name» с несколькими тысячами записей. Каков эффективный способ узнать, какие строки в $ foo не являются «именем» в записи в «people», не отправляя запрос для каждой строки в $ foo?

Итак, я хочу узнать, какие строки в $ foo еще не были введены в 'people'.

Обратите внимание, что очевидно, что все данные должны быть в одном поле в одной точке. Цель состоит в том, чтобы сделать это одновременно с минимизацией количества запросов и объема обработки php.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
0
2 507
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Я бы поместил ваши данные $ foo в другую таблицу и сделал ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ с вашей таблицей имен. В противном случае существует не так много отличных способов сделать это, которые в какой-то момент не включали бы итерацию.

как бы вы использовали LEFT JOIN, чтобы вернуть дату $ foo нет в таблице имен?

Steven Noble 21.10.2008 04:56

Я не уверен, что есть более эффективный способ сделать это, кроме отправки всех строк в базу данных.

В основном есть два варианта: получить список всех строк в MySQL и вытащить их в PHP и провести сравнения или отправить список всех строк на сервер MySQL и позволить ему сделать сравнения. MySQL будет выполнять сравнения намного быстрее, чем PHP, если только список в базе данных не будет намного меньше, чем список в PHP.

Вы можете создать временную таблицу, но в любом случае вы отправите все данные в базу данных.

Вы можете привести пример того, как может выглядеть длинный оператор выбора?

Steven Noble 21.10.2008 05:12

Если подумать, длинный выбор, вероятно, не сработает, вам понадобится идея временной таблицы, принятая в качестве правильного ответа.

acrosman 22.10.2008 00:32

Для нескольких сотен записей просто используйте array_diff () или array_diff_assoc ()

Лучшее, что я могу придумать без использования временной таблицы:

 $list = join(",", $foo);

// fetch all rows of the result of 
// "SELECT name FROM people WHERE name IN($list)" 
// into an array $result

$missing_names = array_diff($foo, $result);

Обратите внимание, что если $ foo содержит пользовательский ввод, его сначала нужно экранировать.

Ага! Заполнителей нет! Не цитируется! Никаких побегов!

bart 21.10.2008 10:59

Ну, закомментированные строки, очевидно, являются псевдокодом. И я упомянул об отсутствии побегов, не так ли? Однако отсутствие цитирования было упущением, мое плохое.

jakber 21.10.2008 11:43
$query = 'SELECT name FROM table WHERE name != '.implode(' OR name != '. $foo);

Да уж, похоже, что он вообще не будет хорошо масштабироваться.

Это должно быть «И», а не «ИЛИ».

Lucas Oman 21.10.2008 06:51
Ответ принят как подходящий
CREATE TEMPORARY TABLE PhpArray (name varchar(50));

-- you can probably do this more efficiently
INSERT INTO PhpArray VALUES ($foo[0]), ($foo[1]), ...;

SELECT People.*
FROM People
 LEFT OUTER JOIN PhpArray USING (name)
WHERE PhpArray.name IS NULL;

А как насчет следующего:

  1. Получите список имен, которые уже есть в базе данных, используя что-то вроде: SELECT name FROM people WHERE name IN (imploded list of names)
  2. Вставьте каждый предмет из возврата array_diff()

Если вы хотите сделать это полностью на SQL:

  1. Создайте временную таблицу с каждым именем в массиве PHP.
  2. Выполните запрос, чтобы заполнить вторую временную таблицу, которая будет включать только новые имена.
  3. Сделайте INSERT ... SELECT из второй временной таблицы в таблицу людей.

Ни один из них не будет очень быстрым, хотя второй вариант может быть немного быстрее.

Другие вопросы по теме