Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Приветствую всех!
есть таблица с некими объектами:
create table t1(
obj_id mediumint unsigned auto_increment primary key,
obj_name char(50)
);
и есть таблица с параметрами для этих объектов заданная в таком виде:
create table t2(
obj_id mediumint unisgned,
param mediumint unsigned,
value mediumint unsigned
);
каждый объект может иметь сколь угодно много параметров
Задача сделать фильтр по _НЕСКОЛЬКИМ_ параметрам.
Когда параметр один, то все естественно делается просто:
SELECT *
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE param=5 AND value >50
а вот когда нужно например выбрать объекты у которых param=5 имеет value > 50 и param=7 имеет value=10 то вот так уже естественно не напишешь
SELECT *
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE param=5 AND value >50 AND param=7 AND value=10
Буду вам очень благодарен если подскажите как правильно составить запрос для выборки по нескольким параметрам
Неактивен
t2 надо присоединять два раза:
FROM t1 JOIN t2 n1 ON … JOIN t2 n2 ON …
WHERE (n1.param = 5 AND … ) AND (n2.param = 7 AND … ).
Неактивен
Неактивен
Блина, мне пора в отпуск. Стопудово пора. Вот я уже вижу самолет,
летящий на теплое море. И никакого MySQL!
Неактивен
vaspet написал:
SELECT *
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE (param=5 AND value >50) OR (param=7 AND value=10)
учите математику!
такой вариант выберет записи у которых хотя бы один из параметров будет подходить ... а пользователь в приложении задает например несколько параметров и они должны быть соблюдены ВСЕ! т.е например юзер задал искать марку авто audi ( например param=5 и value=30 ) с кузавами седан ( param=10 и value=9) .. дак вот запрос по типу вышеприведенного выберет также объекты с кузовами седан, но маркой не audi ... и все ауди с кузовами не седан.
Отредактированно savit (08.09.2010 22:39:14)
Неактивен
В данный момент остановился на таком варианте ... исходя из того что кол-во параметров по которым нужно выбрать объекты известно ( например 2 как я указывал в изначально сообщении ), можно записать так
SELECT t1.obj_id, count( * ) c, t1.obj_name, t2.param, t2.value
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE (
param =5
AND value >50
)
OR (
param =7
AND value=10
)
GROUP BY t1.obj_id
HAVING c = 2
все объекты у которых c не равно 2 под какой-то из параметров соответственно не подходят
Неактивен
Задание не тек понял.
SELECT t1.obj_id, count( * ) c, t1.obj_name, t2.param, t2.value
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE (
param =5
AND value >50
)
OR (
param =7
AND value=10
)
GROUP BY t1.obj_id
HAVING c = 2
к сожалению тоже не подходит:
Пример где не работает:
param value
5 58
5 62
вернет 2 записи для одного ID, но только один параметр (5)
Если Ваш вариант оставить и "param" всегда "=", то
"count( * ) c" -> "count( param ) AS c"
Но какой-то запрос не красивый. Надо еше подумать.
Кстати пример paulus'а должен давать правильный результат.
Отредактированно vaspet (09.09.2010 12:37:18)
Неактивен
согласен что пример paulus'а будет давать правильный результат, но при выборе 10 параметрам прийдется делать 10 джойнов что тоже не гуд
насчет неправильного результата для:
param value
5 58
5 62
у одного объекта не может быть 2 одинаковых параметра с разными значениями, только для разных obj_id могут быть заданы одинаковые параметры (param) с разными значениями (value) .. пусть param=5 обозначает вместимость в килограммах, а value=58 или value=62 указывает соответственно на число кг. Один объект не может одновременно иметь вместимость 58 кг и 62 кг => те параметры и их значения что вы привели должны быть для разных объектов
obj_id param value
1 5 58
2 5 62
соответственно запрос:
SELECT t1.obj_id, count( * ) c, t1.obj_name, t2.param, t2.value
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE (
param =5
AND value >50
)
OR (
param =7
AND value=10
)
GROUP BY t1.obj_id
HAVING c = 2
не должен вернуть ничего вообще (!) т.к для приведенного Вами варианта "c" будет равен 1 ( а пользователь хочет выбрать объекты у которых есть точное совпадение по 2 параметрам .. например например вместимость больше 50 и диаметр бака равный 10 )
Отредактированно savit (09.09.2010 13:56:31)
Неактивен
не должен вернуть ничего вообще (!) т.к для приведенного Вами варианта "c" будет равен 1
'2'
Насколько я понимаю
SELECT count( param ) as c
FROM t1
INNER JOIN t2 ON t1.obj_id = t2.obj_id
WHERE (
param =5
AND value >50
)
OR (
param =7
AND value=10
)
GROUP BY t1.obj_id
HAVING c = 2
- возврашает количество уникальных "param" для одного транспортного средства
т.е. для табл. вернет 1:
obj_id param value
1 5 58
1 5 62
(такой вариант не сушествует, как мы поняли)
а для табл. вернет 2:
obj_id param value
1 5 58
1 7 10
(такой вариант идентичен count(*))
Неактивен
Страниц: 1