SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 08.09.2010 15:26:53

savit
Завсегдатай
Зарегистрирован: 10.11.2009
Сообщений: 25

Хранение параметров в строках и выборка по нескольким условиям

Приветствую всех!

есть таблица с некими объектами:

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

Буду вам очень благодарен если подскажите как правильно составить запрос для выборки по нескольким параметрам

Неактивен

 

#2 08.09.2010 16:53:46

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Хранение параметров в строках и выборка по нескольким условиям

t2 надо присоединять два раза:

FROM t1 JOIN t2 n1 ON … JOIN t2 n2 ON …
WHERE (n1.param = 5 AND … ) AND (n2.param = 7 AND … ).

Неактивен

 

#3 08.09.2010 19:22:24

vaspet
Завсегдатай
Зарегистрирован: 11.03.2009
Сообщений: 83

Re: Хранение параметров в строках и выборка по нескольким условиям

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)
 


учите математику! smile

Неактивен

 

#4 08.09.2010 19:44:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Хранение параметров в строках и выборка по нескольким условиям

Блина, мне пора в отпуск. Стопудово пора. Вот я уже вижу самолет,
летящий на теплое море. И никакого MySQL! smile

Неактивен

 

#5 08.09.2010 22:15:55

savit
Завсегдатай
Зарегистрирован: 10.11.2009
Сообщений: 25

Re: Хранение параметров в строках и выборка по нескольким условиям

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)
 


учите математику! smile

такой вариант выберет записи у которых хотя бы один из параметров будет подходить ... а пользователь в приложении задает например несколько параметров и они должны быть соблюдены ВСЕ! т.е например юзер задал искать марку авто audi ( например param=5 и value=30 ) с кузавами седан ( param=10 и value=9) .. дак вот запрос по типу вышеприведенного выберет также объекты с кузовами седан, но маркой не audi ... и все ауди с кузовами не седан.

Отредактированно savit (08.09.2010 22:39:14)

Неактивен

 

#6 08.09.2010 23:31:52

savit
Завсегдатай
Зарегистрирован: 10.11.2009
Сообщений: 25

Re: Хранение параметров в строках и выборка по нескольким условиям

В данный момент остановился на таком варианте ... исходя из того что кол-во параметров по которым нужно выбрать объекты известно ( например 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 под какой-то из параметров соответственно не подходят

Неактивен

 

#7 09.09.2010 12:35:48

vaspet
Завсегдатай
Зарегистрирован: 11.03.2009
Сообщений: 83

Re: Хранение параметров в строках и выборка по нескольким условиям

Задание не тек понял.

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)

Неактивен

 

#8 09.09.2010 13:43:26

savit
Завсегдатай
Зарегистрирован: 10.11.2009
Сообщений: 25

Re: Хранение параметров в строках и выборка по нескольким условиям

согласен что пример 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)

Неактивен

 

#9 09.09.2010 23:55:36

vaspet
Завсегдатай
Зарегистрирован: 11.03.2009
Сообщений: 83

Re: Хранение параметров в строках и выборка по нескольким условиям

не должен вернуть ничего вообще (!) т.к для приведенного Вами варианта "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(*))

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson