I use IN to make Intersection
This is an example of usage:
SELECT * FROM `test_oc_product`
WHERE product_id IN ( SELECT product_id FROM test_oc_product_option WHERE option_id = '21' AND value = 'Red' )
AND product_id IN ( SELECT product_id FROM test_oc_product_attribute WHERE attribute_id = '10' )
And here is dump
CREATE TABLE `test_oc_product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`model` varchar(64) NOT NULL,
`sku` varchar(64) NOT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test_oc_product` (`product_id`, `model`, `sku`) VALUES
(1, 'A1', 'A1'),
(2, 'A2', 'A2'),
(3, 'A3', 'A3'),
(4, 'AA', 'AA'),
(5, 'A5', 'A5'),
(6, 'A6', 'A6'),
(7, 'A7', 'A7'),
(8, 'A8', 'A8');
CREATE TABLE `test_oc_product_attribute` (
`product_id` int(11) NOT NULL,
`attribute_id` int(11) NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`product_id`, `attribute_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test_oc_product_attribute` (`product_id`, `attribute_id`, `text`) VALUES
('1', '10', 'Attribute Value 1'),
('2', '11', 'Attribute Value 2');
CREATE TABLE `test_oc_product_option` (
`product_option_id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`option_id` int(11) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`product_option_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test_oc_product_option` (`product_option_id`, `product_id`, `option_id`, `value`) VALUES
(NULL, '1', '21', 'Red'),
(NULL, '2', '21', 'Red'),
(NULL, '3', '21', 'Blue'),
(NULL, '4', '10', 'S');