@zabachok

Как выбрать записи по параметрам хранящимся в другой таблице?

Добрый день!
Имею таблицу неких "объектов", которые пока содержат только идентификатор и название:
CREATE TABLE `object` (
  `object_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`object_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;


INSERT INTO `object` (`object_id`, `name`) VALUES
(1, 'Первый'),
(2, 'Второй'),
(3, 'Третий');

Также есть таблица параметров этих объектов, которая связана с первой таблицей по полю object_id. Она содержит поле param_name которое хранит название параметра и поле value, которое хранит значение это параметра, для этого объекта:
CREATE TABLE `param_value` (
  `praram_value_id` int(11) NOT NULL AUTO_INCREMENT,
  `object_id` int(11) NOT NULL,
  `param_name` varchar(100) NOT NULL,
  `value` int(11) NOT NULL,
  PRIMARY KEY (`praram_value_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

INSERT INTO `param_value` (`praram_value_id`, `object_id`, `param_name`, `value`) VALUES
(1, 1, 'width', 3),
(2, 2, 'width', 2),
(3, 3, 'width', 5),
(4, 1, 'height', 10),
(5, 2, 'height', 7),
(6, 3, 'height', 5);


Суть:
Мне нужно выбрать все объекты, которые содержат определенные значения некоторых параметров, затем желательно научится их сортировать.
Я почти добился правильной выборки, но мой запрос находит все объекты, у которых подходит хотя бы один параметр:
SELECT a.object_id,
	GROUP_CONCAT(CONCAT(b.param_name,":",b.value) SEPARATOR "|") AS params,
    a.object_id,
    a.name
FROM `object` a, `param_value` b
WHERE 
	a.object_id = b.object_id AND 
	((b.param_name='width' AND b.value > 2) OR 
	(b.param_name='height' AND b.value > 3 AND b.value < 7))
GROUP BY a.object_id

Если заменить OR на AND, то это приводит к тому что он ищет сразу два param_name в одной записи, что невозможно и ничего не находит.
Как сортировать их по одному или нескольким параметрам я совсем не знаю.
Не хочется делать вложенные запросы.
Спасибо за помощь!
  • Вопрос задан
  • 2377 просмотров
Пригласить эксперта
Ответы на вопрос 2
@pihel
Sql, Oracle, pl/sql, BI, ETL, php, olap
Может использовать UNION или делать JOIN `param_value` столько раз, сколько param_name ?
Ответ написан
Комментировать
@zabachok Автор вопроса
Сейчас у меня такой вариант. Все цели достигнуты, но не ясно насколько он производителен. Его можно как-то оптимизировать?
SELECT a.object_id,
	b.value AS `width`,
	c.value AS `height`,
    a.name
FROM `object` a
LEFT JOIN `param_value` b ON a.object_id = b.object_id AND 
	(b.param_name='width' AND b.value > 2)
LEFT JOIN `param_value` c ON a.object_id = c.object_id AND 
	(c.param_name='height' AND c.value > 3 AND c.value < 7)
WHERE 1
GROUP BY a.object_id
HAVING `width` IS NOT NULL AND `height` IS NOT NULL
ORDER BY `width` DESC
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы