как опустить строки mysql, соответствующие другой таблице, если ни одна из них не уникальна

#mysql

Вопрос:

У меня есть две таблицы, в одной из которых содержатся потенциальные элементы, в другой-завершенные элементы.

Таблица потенциальных товаров в настоящее время содержит записи, которые также были добавлены в таблицу завершенных товаров. Я хочу удалить (либо удалив, либо выбрав новые результаты) уже завершенные элементы из списка потенциальных элементов.

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

Реальный набор данных, конечно, больше, но вот примеры.

Потенциальные предметы:

 mysqlgt; select * from stack;  ---------- ------ ------  | stack_id | type | name |  ---------- ------ ------  | 3 | a | aa | | 4 | b | bb | | 5 | c | cc | | 6 | d | dd | | 7 | a | aa | | 8 | b | bb |  ---------- ------ ------  6 rows in set (0.00 sec)  

Завершенные пункты

 mysqlgt; select * from temp;  ---------- ------ ------  | item_id | type | name |  ---------- ------ ------  | 1 | a | aa | | 2 | b | bb | | 6 | b | bb |  ---------- ------ ------  3 rows in set (0.00 sec)  

Идентификаторы между таблицами не коррелируют, поэтому их следует игнорировать при поиске совпадений.

Я хочу опустить 1 экземпляр a/aa и 2 экземпляра b/bb, так как они были заполнены и существуют в другой таблице.

когда я попробую это:

mysqlgt; select stack.* from stack where (type,name) not in (select type,name from temp);

Я понимаю это:

  ---------- ------ ------  | stack_id | type | name |  ---------- ------ ------  | 5 | c | cc | | 6 | d | dd |  ---------- ------ ------  2 rows in set (0.03 sec)  

Но при этом были опущены оба экземпляра type=»a» и name=»aa», и я хочу опустить только один из них (поскольку он существует только один раз в таблице завершенных элементов).

Как мне это получить?

  ---------- ------ ------  | stack_id | type | name |  ---------- ------ ------  | 5 | c | cc | | 6 | d | dd | | 7 | a | aa |  ---------- ------ ------   

Мне все равно, какой экземпляр a/aa будет удален (будь то id=7 или id=3)

Лучшее, что я смог придумать, — это использовать PHP, а не MySQL, чтобы перебирать каждую запись в temp и удалять с ОГРАНИЧЕНИЕМ 1 из стека.

Но я бы предпочел не запускать код для этого, я бы хотел делать это в запросах, так лучше работает в моем рабочем процессе

Спасибо!

Комментарии:

1. Ваш вопрос не совсем ясен. Вы ищете запрос для включения или исключения элементов из одного списка, если они появляются в другом списке?

2. Я хотел бы либо запросить удаление повторяющихся строк, либо выбрать не повторяющиеся строки. Мое текущее решение состоит в том, чтобы использовать php для генерации набора запросов «удалить из…. ограничение 1».

3. Вы ищете первое появление [‘a’, ‘aa’] в списке стеков, тогда вы можете использовать select min(stack_id), type, name from stack group by type, name или select min(stack_id), s.type, s.name from stack s inner join temp using (type, name) group by s.type, s.name таким образом объединить две таблицы.

Ответ №1:

 CREATE TABLE `test`.`stack` (  `stack_id` INT UNSIGNED NOT NULL,  `type` VARCHAR(45) NULL,  `name` VARCHAR(45) NULL,  PRIMARY KEY (`stack_id`));  CREATE TABLE `test`.`temp` (  `item_id` INT UNSIGNED NOT NULL,  `type` VARCHAR(45) NULL,  `name` VARCHAR(45) NULL,  PRIMARY KEY (`item_id`));  

и чем-то вроде этого:

 select  min(stack_id), type, name from stack _s  inner join  (  select min(item_id) item_id, type, name  from temp  group by type, name ) _t using(type, name) group by _s.type, _s.name  

даст вам только один первый пункт в temp:

stack_id Тип Имя
3 a aa
4 b бб