powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Можно ли 1 запросом заменить 3 запроса?
9 сообщений из 9, страница 1 из 1
Можно ли 1 запросом заменить 3 запроса?
    #39711373
Доброй ночи!

Есть такая табличка - хранит привязки опции к категориям - одна категория ко многим опциям.
На скриншоте категория - розовая обводка, опции - зеленая обводка.

Можно ли сделать запросом следующее?
Входящие данные - ID категории = 26, для неё в БД должны остаться только опции с ID= 12, 14, 15 и добавиться опции ID=22, 45
Пока что есть вариант - сравнивать в PHP два массива - то, что есть и то, что должно быть, в зависимости от результатов сравнения какие-то опции удалять, какие-то добавлять...??? В худшем сценарии получается 3 запроса к БД...(((

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
--
-- Структура таблицы `options_in_cat`
--

CREATE TABLE IF NOT EXISTS `options_in_cat` (
  `id` int(11) NOT NULL,
  `option_id` int(11) NOT NULL,
  `cat_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

--
-- Дамп данных таблицы `options_in_cat`
--

INSERT INTO `options_in_cat` (`id`, `option_id`, `cat_id`) VALUES
(1, 1, 13),
(2, 2, 13),
(3, 3, 13),
(4, 4, 13),
(5, 5, 13),
(6, 6, 13),
(7, 17, 13),
(8, 18, 13),
(9, 19, 13),
(10, 20, 13),
(11, 21, 13),
(12, 12, 26),
(13, 13, 26),
(14, 14, 26),
(15, 15, 26),
(16, 16, 26);

--
-- Индексы сохранённых таблиц
--

--
-- Индексы таблицы `options_in_cat`
--
ALTER TABLE `options_in_cat`
  ADD PRIMARY KEY (`id`);

...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39711375
вот картинка таблички
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39711406
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Олег КотейкинВ худшем сценарии получается 3 запроса к БД...Два.
Код: sql
1.
2.
3.
4.
5.
6.
7.
DELETE 
FROM options_in_cat
WHERE cat_id = 26
  AND option_id NOT IN (12, 14, 15);

INSERT INTO options_in_cat (option_id, cat_id)
VALUES (22, 26), (45, 26);


Но предварительно следует options_in_cat.id сделать автоинкрементным.

Если это по каким-то невменяемым причинам невозможно, то второй запрос превращается в какую-нибудь дурь типа
Код: sql
1.
2.
3.
4.
5.
6.
7.
INSERT INTO options_in_cat (id, option_id, cat_id)
SELECT m.id + CASE WHEN v.option_id = 22 THEN 1 ELSE 2 END, v.option_id, 26
FROM (SELECT MAX(id) id
       FROM options_in_cat) m,
     (SELECT 22 option_id
      UNION ALL
      SELECT 45) v;

Возможные интерференции - за свой счёт. В 8-й версии можно слегка упроститься, переместив всю предрасчётную хрень в секцию WITH.
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39711501
AkinaНо предварительно следует options_in_cat.id сделать автоинкрементным.

спасибо за ответ! да. сорри, забыл указать, options_in_cat.id автоинкрементный!
Т.е. в моем случае не все так печально?))

И еще небольшой нюанс - я спросил неоднозначно, вот здесь:
авторВходящие данные - ID категории = 26, для неё в БД должны остаться только опции с ID= 12, 14, 15 и добавиться опции ID=22, 45
на самом деле это только я знаю что оставить а что добавить, на самом деле-то приходит массив - вот это должно быть в БД - 12,14,15,22,45 - и точка.
А чтобы массив приходил двумя кусками, то для этого потребуется php-обработка, чего хотелось бы избежать.
Или сделать php-обработку, но тогда обойтись одним sql-запросом.
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39711506
Akina,

вот еще пришел в голову вариант - а что если писать в таблицу ОДНИМ запросом - банальную вставку без всяких предварительных проверок, т.е. прямо так и пишем - для категории id=26 вставляем строки 12,14,15,22,45, т.е. в таблице будет накапливаться некая избыточность, а отсеивать уже при выводе из БД? так как функция этой таблички - упростить отображение и выбор в АДМИНКЕ, т.е. юзер всегда один...
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39711522
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Олег Котейкинна самом деле-то приходит массив - вот это должно быть в БД - 12,14,15,22,45 - и точка.Ну так в чём проблема?

Первый запрос:
Код: sql
1.
2.
3.
4.
DELETE 
FROM options_in_cat
WHERE cat_id = 26
  AND option_id NOT IN (12,14,15,22,45);

Он удаляет все записи, которых быть не должно.

Второй запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
INSERT INTO options_in_cat (option_id, cat_id)
SELECT option_id, 26
FROM (SELECT 12 option_id
      UNION
      SELECT 14
      UNION
      SELECT 15
      UNION
      SELECT 22
      UNION
      SELECT 45) tmp
WHERE option_id NOT IN (SELECT option_id
                        FROM options_in_cat 
                        WHERE cat_id = 26)

Он вставляет недостающие записи.

При наличии уникального индекса по (option_id, cat_id) второй запрос упрощается до
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
INSERT IGNORE INTO options_in_cat (option_id, cat_id)
SELECT option_id, 26
FROM (SELECT 12 option_id
      UNION
      SELECT 14
      UNION
      SELECT 15
      UNION
      SELECT 22
      UNION
      SELECT 45) tmp
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39712174
Akina,

да. спасибо.

Но запросов таки не два0) Вложенные же я считаю как отдельные.Хотя для админки скорость не так важна...
Тут еще в чем нюанс - чтобы сформировать вот этот подзапрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT 12 option_id
      UNION
      SELECT 14
      UNION
      SELECT 15
      UNION
      SELECT 22
      UNION
      SELECT 45


придется все-таки городить конструкцию на php, ведь перечень айдишек приходит массивом...

Тогда уж наверное в цикле и делать запросы:
1. mysql запрос текущей комбинации айдишек
2. array_diff (входящий массив, массив из п.1)- получим айдишки к удалению
3. array_diff (массив из п.1, входящий массив) - получим айдишки к вставке
4. mysql запрос delete in (п.2)
5. mysql запрос insert в цикле по массиву изп.3

))))
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39712190
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Олег Котейкин,
как вариант
- выгрузить массив в файл в формате option_id, 26,
- удалить всю 26 категорию,
- загрузить из файла по LOAD DATA INFILE
...
Рейтинг: 0 / 0
Можно ли 1 запросом заменить 3 запроса?
    #39712197
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Олег КотейкинВложенные же я считаю как отдельные. А тогда чего бы каждую кляузу за отдельный запрос не считать? так ещё больше получится...

Олег Котейкинчтобы сформировать вот этот подзапрос
[skipped]
придется все-таки городить конструкцию на php, ведь перечень айдишек приходит массивом...Кто мешает разобрать массив на элементы? особенно если где-то на сервере есть таблица чисел (кстати, полезная штука).

Олег КотейкинТогда уж наверное в цикле и делать запросы:Нет, если Вы PHP знаете намного лучше, чем MySQL - делайте так... работать-то оно будет.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Можно ли 1 запросом заменить 3 запроса?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]