I'm using n:m
relationship to add "attributes" to "products", because I want to retrieve the same attribute to more than one product.
My table:
When perform a query like this:
SELECT
PROD.id AS PRODUCT_ID,
PROD.name AS PRODUCT_NAME,
PROD.price AS PRODUCT_PRICE,
ATTR.id AS ATTR_ID,
ATTR.attribute AS ATTR_NAME
FROM
products PROD,
attributes ATTR,
products_has_attributes PHA
WHERE
PROD.id = PHA.products_id AND ATTR.id = PHA.attributes_id
Return this:
PRODUCT_ID | PRODUCT_NAME | PRODUCT_PRICE | ATTR_ID | ATTR_NAME
---------------------------------------------------------------------------
1 | i30 | 29000.00 | 1 | a/c
1 | i30 | 29000.00 | 2 | sunroof
2 | onix | 350000.00 | 2 | sunroof
3 | hilux | 80000.00 | 1 | a/c
3 | hilux | 80000.00 | 3 | leather seat
3 | hilux | 80000.00 | 4 | new
If "filter" the SELECT
by products with "sunroof":
WHERE
PROD.id = PHA.products_id AND ATTR.id = PHA.attributes_id
AND
ATTR.attribute = 'sunroof'
Return this:
PRODUCT_ID | PRODUCT_NAME | PRODUCT_PRICE | ATTR_ID | ATTR_NAME
---------------------------------------------------------------------------
1 | i30 | 29000.00 | 2 | sunroof
2 | onix | 350000.00 | 2 | sunroof
SELECT found two cars (with sunroof), but I need to return all attributes of founded products, in other worlds, I need return like this:
PRODUCT_ID | PRODUCT_NAME | PRODUCT_PRICE | ATTR_ID | ATTR_NAME
---------------------------------------------------------------------------
1 | i30 | 29000.00 | 1 | a/c
1 | i30 | 29000.00 | 2 | sunroof
2 | onix | 350000.00 | 2 | sunroof
If SELECT products with "sunroof" and "new":
WHERE
PROD.id = PHA.products_id AND ATTR.id = PHA.attributes_id
AND
ATTR.attribute = 'sunroof' AND ATTR.attribute = 'new'
I want return this:
PRODUCT_ID | PRODUCT_NAME | PRODUCT_PRICE | ATTR_ID | ATTR_NAME
---------------------------------------------------------------------------
3 | hilux | 80000.00 | 1 | a/c
3 | hilux | 80000.00 | 3 | leather seat
3 | hilux | 80000.00 | 4 | new
Database example (with INSERT
/products):
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;
CREATE TABLE IF NOT EXISTS `mydb`.`products` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
`price` DECIMAL (10,2),
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `mydb`.`attributes` (
`id` INT NULL AUTO_INCREMENT,
`attribute` VARCHAR(45) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `mydb`.`products_has_attributes` (
`products_id` INT(11) NOT NULL,
`attributes_id` INT NOT NULL,
PRIMARY KEY (`products_id`, `attributes_id`),
INDEX `fk_products_has_attributes_attributes1_idx` (`attributes_id` ASC),
INDEX `fk_products_has_attributes_products_idx` (`products_id` ASC),
CONSTRAINT `fk_products_has_attributes_products`
FOREIGN KEY (`products_id`)
REFERENCES `mydb`.`products` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_products_has_attributes_attributes1`
FOREIGN KEY (`attributes_id`)
REFERENCES `mydb`.`attributes` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
INSERT INTO `attributes` (`id`, `attribute`) VALUES
(1, 'a/c'),
(2, 'sunroof'),
(3, 'leather seat'),
(4, 'new');
INSERT INTO `products` (`id`, `name`, `price`) VALUES
(1, 'i30', '29000.00'),
(2, 'onix', '350000.00'),
(3, 'hilux', '80000.00');
INSERT INTO `products_has_attributes` (`products_id`, `attributes_id`) VALUES
(1, 1),
(1, 2),
(2, 2),
(3, 1),
(3, 3),
(3, 4);
SELECT
PROD.id AS PRODUTO_ID,
PROD.name AS PRODUTO_NOME,
PROD.price AS PRODUTO_PRECO,
ATTR.id AS ATTRIBUTO_ID,
ATTR.attribute AS ATTRIBUTO_NOME
FROM
products PROD,
attributes ATTR,
products_has_attributes PHA
WHERE
PROD.id = PHA.products_id AND ATTR.id = PHA.attributes_id