Z
Z
zabachok2014-08-20 12:50:15
MySQL
zabachok, 2014-08-20 12:50:15

How to select records by parameters stored in another table?

Good afternoon!
I have a table of some "objects", which so far contain only an identifier and a name:

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, 'Третий');

There is also a table of parameters for these objects, which is linked to the first table by the object_id field. It contains the param_name field which stores the name of the parameter and the value field which stores the value of this parameter for this object:
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);

Essence:
I need to select all objects that contain certain values ​​of some parameters, then it is desirable to learn how to sort them.
I almost got the correct selection, but my query finds all objects that match at least one parameter:
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

If you replace OR with AND, then this leads to the fact that he is looking for two param_names at once in one record, which is impossible and does not find anything.
How to sort them by one or more parameters, I do not know at all.
I don't want to do nested queries.
Thanks for the help!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Skahin, 2014-08-20
@pihel

Can use UNION or do JOIN `param_value` as many times as param_name ?

Z
zabachok, 2014-08-21
@zabachok

Now I have this option. All goals are achieved, but it is not clear how productive it is. Can it be optimized somehow?

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question