Я ничего не имею ввиду, нужна выборка записей, с повторяющимися значениями login. Типа вот так: Код (Text): SELECT a.id, a.name FROM TableWithDuplicates a WHERE EXISTS(SELECT b.id FROM TableWithDuplicates b WHERE a.name = b.name AND a.id <> b.id);
Да какая разница как он передается? Может он вообще по ssh подгружается другим серваком по крону. Тебе на вход передают имя файла, у него есть расширение. Всё.
Ну с первой задачей ты сто процентов не справился, там должно было быть что-то вроде (на скорую руку) Код (Text): select * from Users u where (select count(1) from Users u1 where u1.login=u.login) > 1; Второе тебе показал @romach. Тут типично для ООП надо абстрагироваться откуда получен файл, тебя не просили полностью рабочий модуль написать, тебя просили простенькую иерархию сделать. Пока я писал свой, @romach свой запрос дал... В общем, не справился с заданием, уж извини...
Да про дубликаты я не срастил просто. Запрос не сложный, но я бы его избежал. Лучше обработкой дубликатов нагрузить php машину чем серв бд.
Понятно, что во втором задании не предполагается, что передаётся $_FILES["xxx"]["tmp_name"], предполагается, что расширение известно. БД справится, это раз, зачем мучать php. А два - надо делать то, что попросили в задании. Самодеятельность в работе не приветствуется. Вот у меня есть заказчик, который после каждого успешной отправки всплывающей формы, требует переходить на страничку с текстом "Спасибо большое". Лично я бы не стал выделять отдельную страничку под такую "важную" задачу, вывел бы второе окошко, но его сеошник убеждён в том, что это необходимо, чтоб ставить цели в метрике и аналитиксе. Ну и хрен с ним, делаю, так как просят.
Нет php обработает данные быстрее. Чем бд. Тут не будут циркулировать запрсоы в цикле для проверки дубликатов. А значи тмодно обойтись без вложенных запросов и join. Я использую join только тогда когда не знаю как не делать так чтобы не делать запросы в цикле.
С чего вдруг? Чтоб это сделать на php, тебе надо выбрать всю таблицу в память. Нахрена? При индексе по login вложенный запрос в моём случае отработает ун моменто. Сервера БД пишут люди поумнее нас с тобой, и не на php, а на C, который в сотни раз быстрее. У меня вообще правило: вся фильтрация на БД. Нарушил его только один раз пока - когда у меня в условия фильтрации пришлось включить длину маршрутов, рассчитанную Яндекс.картами (к тому же, и у яндекса и у гугла есть условие, запрещающее пользовать это api только на серваке без отображения проложенного маршрута на картах). И то, сначала у меня БД считает расстояние по прямой, отфильтровывает слишком большое (поскольку длина маршрута не может быть меньше длины по прямой никак), и только потом уже результат передаётся яндексу.
Где тут множественные запросы? Или ты думаешь оно вот так в лоб все херачит, без фильтрации, индексов и кэшей?
Согласен, но не в этом случае. Обычно ложится, если там 6-7 join в одном запросе. И ещё зависит от того, насколько продуманы индексы. Можно сделать так, что и не ляжет.
Да хоть тысячами, если ты про join и вложенные запросы говоришь "кому как нравится", то таки иди учи. Потому что важно лишь то, что нравится планировщику запроса )
Провёл эксперимент на большой таблице. Таблицу Код (Text): CREATE TABLE `doubles` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `login` VARCHAR(50) NOT NULL, `some_info` TEXT NOT NULL, PRIMARY KEY (`id`), INDEX `login` (`login`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB; заполнил с помощью PHP: <?php require_once __DIR__ . "/vendor/autoload.php"; $db= new mysqli("localhost", "root", "", "test"); $faker = Faker\Factory::create(); $logins = []; for ($i = 1; $i <= 10000; $i++) { do { $login = $faker->words(3, true); } while (in_array($login, $logins)); $logins[] = $login; } $stmt = $db->prepare("insert into doubles set login=?, some_info=?"); for ($i = 1; $i < 500000; $i++) { $stmt->bind_param("ss", $login, $some_info); $login = $logins[rand(0, 10000)]; $some_info = $faker->paragraphs(6, true); $stmt->execute(); } потом попробовал так три запроса: PHP: <?php $db = new mysqli("localhost", "root", "r124h5rgn", "test"); $t1 = microtime(true); $res = $db->query("SELECT a.id, a.login FROM doubles a WHERE EXISTS(SELECT b.id FROM doubles b WHERE a.login = b.login AND a.id <> b.id);", MYSQLI_USE_RESULT); while ($res->fetch_assoc()); echo microtime(true) - $t1, " time A\n"; $res->free_result(); $t1 = microtime(true); $res = $db->query("SELECT a.id, a.login FROM doubles a WHERE (SELECT count(1) FROM doubles b WHERE a.login = b.login) > 1;", MYSQLI_USE_RESULT); while ($res->fetch_assoc()); echo microtime(true) - $t1, " time B\n"; $res->free_result(); $t1 = microtime(true); $res = $db->query("select a.id, a.login from doubles a", MYSQLI_USE_RESULT); while ($res->fetch_assoc()); echo microtime(true) - $t1, " TIME C\n"; $res->free_result(); Последний без условия, чтоб было с чем сравнить. Получилось, что запрос от @romach работает в 3 раза быстрее моего, за вполне допустимые 5 секунд, а вот мой запрос плохой, признаю, работает долго, 17 секунд. Запрос без условия - одну секунду. Но тут надо учитывать, что я взял маловато уникальных логинов, ситуация получилась, что у меня все 500 000 дубли, худший случай. Когда генерацию запускал, не подумал. --- Добавлено --- При этом исполнение запросов в HeideSQL показывает интересную штуку: Код (Text): SELECT a.id, a.login FROM doubles a WHERE EXISTS(SELECT b.id FROM doubles b WHERE a.login = b.login AND a.id <> b.id); /* Затронуто строк: 0 Найденные строки: 499 946 Предупреждения: 0 Длительность 1 запрос: 0,032 sec. (+ 4,531 sec. network) */ SELECT a.id, a.login FROM doubles a WHERE (SELECT count(1) FROM doubles b WHERE a.login = b.login) > 1; /* Затронуто строк: 0 Найденные строки: 499 946 Предупреждения: 0 Длительность 1 запрос: 0,047 sec. (+ 17,110 sec. network) */ Честно говоря, я не совсем понимаю, что за время он даёт в скобках.
А так? ) Код (Text): SELECT id, login, COUNT(login) as num FROM doubles WHERE true GROUP BY login HAVING num > 1 ORDER BY num DESC
@Dmitriy A. Arteshuk, так ты не получишь все дубли. Твой запрос в моём случае выдаст 10000 уникальных логинов, и сколько раз каждый использовался (хотя и работает мгновенно). А надо было, чтоб ещё id всех дублей были. Хотя ты навёл меня на мысль, и вот запрос-победитель: Код (Text): select group_concat(id separator ','), login,count(login) c from doubles group by login having c > 1; /* Затронуто строк: 0 Найденные строки: 10 000 Предупреждения: 0 Длительность 1 запрос: 0,016 sec. (+ 0,687 sec. network) */ Если действительно результат надо разобрать на php, то лучше не придумать, разбить потом это из php на отдельные id элементарно
Старая тема разделена на две https://php.ru/forum/threads/klassy-polimorfizm-interfejsy-final.63481/ https://php.ru/forum/threads/vyborka-ili-podschet-duplikatov.63480/
В худшем случае (который я нагенерировал) этот запрос тоже работает медленно. Вернее, долго возвращает результаты, я так понял, что время уходит не на запрос, а на передачу результатов клиенту. Хотя почему MYSQLI_USE_RESULT процесс не ускоряет, я не понял