Помогите сформировать SQL запрос

grishkov

Новичок
Помогите сформировать SQL запрос

Добрый день! Как сделать в запросе операцию пересечения множества индексов. Есть таблица такого вида:

id | var1 | var2 | var3
1 | 1 | 0 | 0
1 | 0 | 1 | 0
1 | 0 | 0 | 1
2 | 1 | 0 | 0
2 | 0 | 1 | 0
2 | 0 | 0 | 0

Нужно вывести все id для которых (в разных строках) все var1, var2, var3 равны 1.

В данном примере правильным выводом должен быть id=1
id=2 не подходит т.к. с таким индексом нет var3=1

Заранее спасибо, а то запарился с таким индексом..
 

zerkms

TDD infected
Команда форума
[sql]
SELECT `id` FROM `table` GROUP BY `id` HAVING MAX(`var1`) + MAX(`var2`) + MAX(`var3`) = 3
[/sql]

Это при условии, что там только 1/0 и что в каждом ряду только одна единица.
 

grishkov

Новичок
Спасибо, но увы в реальности будет не так... В каждом ряду будет несколько значений и они будут отличаться от 1. Думаю поэтому тут нужно использовать операцию "=" для проверки единиц.
 

Gas

может по одной?
Код:
SELECT id, 
       GROUP_CONCAT(var1 ORDER BY var1 ASC) AS v1, 
       GROUP_CONCAT(var2 ORDER BY var2 ASC) AS v2, 
       GROUP_CONCAT(var3 ORDER BY var3 ASC) AS v3
FROM `table`
GROUP BY id
HAVING IF(v1=v2, v2=v3, FALSE)
?
 

Gas

может по одной?
сейчас ещё окажется что количество var1..varN может меняться alter тейблами :)
 

grishkov

Новичок
Хорошо, выкладываю реальный код)

Есть вот такая таблица:
CREATE TABLE IF NOT EXISTS `tbl_catalog_FieldVal` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_product` int(11) NOT NULL,
`id_field` int(11) NOT NULL,
`id_part` int(11) NOT NULL,
`type` text NOT NULL,
`val` text NOT NULL,
`position` int(11) NOT NULL,
PRIMARY KEY (`id`)
)

Нужно вытащить из нее значения столба id_product, которому будут например соответствовать вот такие значения других столбцов:

(id_field=70 AND val=28) AND
(id_field=28 AND position=0 AND val>=100)

Вот некоторые данные из таблицы:
INSERT INTO `tbl_catalog_FieldVal` (`id`, `id_product`, `id_field`, `id_part`, `type`, `val`, `position`) VALUES
(1012, 606, 70, 15, 'sel', '28', 0),
(1062, 605, 70, 15, 'sel', '28', 0),
(2700, 726, 70, 53, 'sel', '28', 0),
(941, 55, 28, 15, 'txt', '120', 0),
(971, 240, 28, 15, 'txt', '110', 0),
(1489, 719, 28, 13, 'txt', '100', 0),
(2109, 634, 28, 35, 'txt', '110', 0),
(2143, 721, 28, 37, 'txt', '150', 0),
(186, 225, 35, 7, 'check', '1', 0),
(187, 225, 37, 7, 'check', '0', 0),
(313, 225, 31, 7, 'sel', '14', 0),
(2113, 634, 42, 36, 'txt', '56', 2);
 

dimagolov

Новичок
grishkov, почему у тебя `val` text, а в условии val=28? и вообще там ВЕЗДЕ числовые значения.
почему у тебя `type` text, в реально у тебя там строки длинной не более 5 символов?

[sql](id_field=70 AND val=28) AND
(id_field=28 AND position=0 AND val>=100)[/sql]
нихрена не понятно. (id_field=70 AND val=28) и (id_field=28 AND position=0 AND val>=100) это 2 разных условия для 2-х разных строк?

хорошо бы рассказать смысл полей и смысл запроса, потому что кажется, что база спроектирована через жопу.
 

grishkov

Новичок
Автор оригинала: dimagolov
grishkov, почему у тебя `val` text, а в условии val=28? и вообще там ВЕЗДЕ числовые значения.
почему у тебя `type` text, в реально у тебя там строки длинной не более 5 символов?

[sql](id_field=70 AND val=28) AND
(id_field=28 AND position=0 AND val>=100)[/sql]
нихрена не понятно. (id_field=70 AND val=28) и (id_field=28 AND position=0 AND val>=100) это 2 разных условия для 2-х разных строк?

хорошо бы рассказать смысл полей и смысл запроса, потому что кажется, что база спроектирована через жопу.
1. почему у тебя `val` text, а в условии val=28
- я дал только часть данных, в реальности в этой таблице хранится дофига текстовых данных. В MySql есть неявное преобразование данных. Если Mysql видит математический оператор, то он преобразовывает текстовый тип в числовой, поэтому тут ничего страшного нет, все должно нормально работать.

2.нихрена не понятно. (id_field=70 AND val=28) и (id_field=28 AND position=0 AND val>=100) это 2 разных условия для 2-х разных строк?
- это два условия при выполнении которых должен выбираться значение id_product, если не выполняется хотябы одно условие, то id_product не выбирается из таблицы.

В общем есть каталог товаров который состоит из полей разного типа. Структуру таблицы в котором все это дело хранится я дал и часть данных тоже.

Нужно вытащить из таблицы tbl_catalog_FieldVal все значения id_product без дублей, которые бы одновременно удовлетворяли следующим критериями:
1. (id_field=70 AND val=28)
2. (id_field=28 AND position=0 AND val>=100).

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

dimagolov

Новичок
grishkov, ты это разрабатываешь или дописываешь один запрос к существующей и наполненной данными БД?

Буду признателен, если кто-нибудь скажет как вытащить id_product для конкретно этого примера, по аналогии я потом соображу как вытаскивать другие комбинации данных.
так как очевидно, что одновременно условия 1 и 2 для одной строки удовлетворяться не могут, то придется джойнить таблицу на себя по `id_product` и накладывать условия на основную и приджойненую часть, потом делать группировку по тому же `id_product`.

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

grishkov

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

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

dimagolov

Новичок
[sql]select ....
from `tbl_catalog_FieldVal` as t1
inner join `tbl_catalog_FieldVal` as t2 on t1.`id_product` = t2.`id_product`
where
(t1.id_field=70 AND t1.val=28) AND
(t2.id_field=28 AND t2.position=0 AND t2.val>=100)
group by t1.`id_product`[/sql]
 

grishkov

Новичок
dimagolov, огромное спасибо, все работает как надо!!

Слушай, если еще нужно будет одно условие добавить, например:
id_field = 70 AND val = 30 То куда его добавлять?
 

dimagolov

Новичок
grishkov, очевидно, что все взаимоисключающие условия должны строиться на дополнительных приджойненых копиях.
 
Сверху