Intereting Posts
Вызов cron дважды или три раза Предупреждение PHP-разработчика xdebug Получить числа из строки с помощью PHP Как использовать preg_replace_callback? подготовленные заявления – создание единого метода * Как создать правильный класс расширения mysqli с подготовленными операторами? Zend Framework – последний код для выполнения перед компоновкой Фильтр the_content не возвращает html-код, любой заменитель? Обновление Zend_Auth_Storage после редактирования профиля пользователя Используя PHP для шифрования изображения для хранения в MySQL BLOB, затем расшифруйте и распечатайте Php parse links / emails Почему нет больше двоичных файлов Windows для расширений PECL, таких как pecl_http? Что это за регулярное выражение, ищущее Как получить календарную неделю, чувствительную к году? дата («W») возвращает 52 на 1 января Безопасность – сеансы (использование по умолчанию – Cookie) по сравнению с локальным хранилищем

Запрос MySQL возвращает нежелательные строки при извлечении строк на основе конкретных комбинаций тегов

Я запускаю PHP + MySQL на своем ПК с Windows 8. У меня есть таблица mytable как mytable ниже;

 ╔═════════╦══════╦═════╗ ║ product ║ tag ║ lot ║ ╠═════════╬══════╬═════╣ ║ 1111 ║ 101 ║ 2 ║ ║ 1111 ║ 102 ║ 5 ║ ║ 2222 ║ 103 ║ 6 ║ ║ 3333 ║ 104 ║ 2 ║ ║ 4444 ║ 101 ║ 2 ║ ║ 5555 ║ 101 ║ 2 ║ ║ 5555 ║ 102 ║ 5 ║ ║ 6666 ║ 102 ║ 2 ║ ║ 6666 ║ 103 ║ 5 ║ ║ 7777 ║ 101 ║ 2 ║ ║ 7777 ║ 102 ║ 5 ║ ║ 7777 ║ 103 ║ 6 ║ ║ 8888 ║ 101 ║ 1 ║ ║ 8888 ║ 102 ║ 3 ║ ║ 8888 ║ 103 ║ 5 ║ ║ 9999 ║ 101 ║ 6 ║ ║ 9999 ║ 102 ║ 8 ║ ╚═════════╩══════╩═════╝ 

У меня есть вход 101 , 102 . Я хочу, чтобы выход понравился;

 2,5 6,8 

Запрос будет искать комбинации 101,102 , 101,102 и возвращает те же самые комбинации с другим номером партии . Наряду с этим, я хочу избежать дублирования строк. Здесь 1111 и 5555 имеют те же теги с одинаковыми номерами партий для tag s (одни и те же комбинации с одинаковыми лотами), поэтому я хочу только одну строку вместо двух строк. Несмотря на то, что 8888 имеет теги 101 и 102 с разными lot s, его нельзя рассматривать для листинга, так как он включает в себя также тэг 103 . Короче говоря, я хочу продукты с точной комбинацией 101, 102 , и я не хочу продуктов с любыми дополнительными тегами, и я не хочу ничего с отсутствующими тегами.

У меня есть запрос, как показано ниже;

 SELECT DISTINCT GROUP_CONCAT(m.lot) FROM mytable m WHERE m.tag IN (101,102) AND (SELECT COUNT(m.product) FROM mytable m2 WHERE m.product = m2.product)>1 GROUP BY m.product; 

который возвращается;

 2,5 2 5,2 1,3 6,8 

Как я могу это исправить? Есть ли лучший способ выполнить то, что я ищу?

Вот скрипка, начинающаяся с http://sqlfiddle.com/#!9/d11d6

Related of "Запрос MySQL возвращает нежелательные строки при извлечении строк на основе конкретных комбинаций тегов"

Я предлагаю использовать для этого простое соединение:

 SELECT DISTINCT a.lot, b.lot FROM mytable a INNER JOIN mytable b ON b.product = a.product AND NOT EXISTS (SELECT * FROM product WHERE tag NOT IN (a.tag, b.tag)) WHERE a.tag = 101 and b.tag = 102 

Мне интересно, делает ли это то, что вы хотите:

 select group_concat(lot order by lot) from mytable group by product having group_concat(tag order by tag) = '101,102'; 

Кажется, это возвращает желаемые результаты. Это будет немного более эффективно с предложением where :

 select group_concat(lot order by lot) from mytable where tag in ('101', '102') group by product having group_concat(tag order by tag) = '101,102'; 

Выполняя группу по продукту, а предложение HAVING явно ищет ТОЛЬКО те продукты, которые имеют как 101, так и 102 и NO OTHER. Как только каждый продукт имеет квалификацию, включены конкатенированные партии. Если у другого есть такая же конкатенация, возвращается только один набор. Из-за ваших повторяющихся записей одного и того же тега 101 внутри продукта мне остается только, если один из них найден независимо от его дублирования, следовательно, MAX () для 101 и 102 оба = 1 соответственно.

 select DISTINCT group_concat( DISTINCT m.lot ORDER BY m.lot ASC SEPARATOR ',' ) from myTable m group by m.product having MAX( case when m.tag = '101' then 1 else 0 end ) = 1 AND MAX( case when m.tag = '102' then 1 else 0 end ) = 1 AND sum( case when m.tag in ( '101', '102' ) then 0 else 1 end ) = 0; 

И если вы хотите увидеть, как сравнивается каждый отдельный продукт, удалите предложение HAVING, чтобы увидеть их соответствующие значения

 select m.product, group_concat( DISTINCT m.lot ORDER BY m.lot ASC SEPARATOR ',' ), sum( case when m.tag in ( '101', '102' ) then 1 else 0 end ) as WantTags, sum( case when m.tag in ( '101', '102' ) then 0 else 1 end ) as OtherTags from myTable m group by m.product 

Я создал экземпляр SQLFiddle для вас. Немного незначительных вещей. Я изменил имена столбцов на «tag1», «lot1».

 select DISTINCT group_concat( DISTINCT m.lot1 ORDER BY m.lot1 ASC SEPARATOR ',' ) from myTableXYZ m group by m.product having MAX( case when m.tag1 = 101 then 1 else 0 end ) = 1 AND MAX( case when m.tag1 = 102 then 1 else 0 end ) = 1 AND sum( case when m.tag1 in ( 101, 102 ) then 0 else 1 end ) = 0; 

Поэтому мой запрос выполняется против вашего SQLFiddle и имеет результаты

 2,5 1,3,5 6,8