2016-04-30 53 views
5

MySQL seleziona da 3 tabelle.MySQL seleziona prodotti distinti da 3 tabelle

ho questi 5 tabelle:

CREATE TABLE `category` (
    `c_id` int(6) NOT NULL AUTO_INCREMENT, 
    `name` varchar(40) NOT NULL, 
    PRIMARY KEY (c_id) 
); 

CREATE TABLE `product` (
    `p_id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(40) NOT NULL, 
    `brand` varchar(30) NOT NULL, 
    `image_path` varchar(100) DEFAULT NULL, 
    PRIMARY KEY (p_id) 
); 

CREATE TABLE `shop` (
    `s_id` int(6) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `country` varchar(30) NOT NULL, 
    `province` varchar(30) NOT NULL, 
    `city` varchar(30) NOT NULL, 
    `suburb` varchar(30) NOT NULL, 
    `street` varchar(40) DEFAULT NULL, 
    `streetNumber` varchar(40) DEFAULT NULL, 
    `postalCode` int(4) DEFAULT NULL, 
    PRIMARY KEY (s_id) 
) ; 

CREATE TABLE product_category (
p_id INT NOT NULL, 
c_id INT NOT NULL, 
PRIMARY KEY (p_id, c_id), 
FOREIGN KEY (p_id) REFERENCES Product(p_id) ON UPDATE CASCADE, 
FOREIGN KEY (c_id) REFERENCES Category(c_id) ON UPDATE CASCADE 
); 

CREATE TABLE product_shop (
p_id INT NOT NULL, 
s_id INT NOT NULL, 
PRIMARY KEY (p_id, s_id), 
FOREIGN KEY (p_id) REFERENCES product(p_id) ON UPDATE CASCADE, 
FOREIGN KEY (s_id) REFERENCES shop(s_id) ON UPDATE CASCADE 
); 

In sostanza, un prodotto può avere molte categorie. Una categoria può essere assegnata a molti prodotti. Un negozio può avere molti prodotti. Un prodotto può essere in molti negozi.

Vorrei selezionare tutti i prodotti in cui il category.c_id = 2, o category.c_id = 8 e la shop.s_id = 1 o shop.s_id = 2.

I am parzialmente lì con questo :

select * 
from product inner join product_category 
on product_category.p_id=product.p_id 
where (product_category.c_id=2) 
or (product_category.c_id=8) 

che ottiene tutti i prodotti che hanno una categoria id di 2 e anche prodotti con una categoria id di 8, ma ottiene lo stesso prodotto due volte se si ha sia category.c_id = 8 e category.c_id = 2.

Quindi ho provato questo per ottenere prodotti unici:

select DISTINCT(product.p_id) as product 
from product inner join product_category 
on product_category.p_id=product.p_id 
where (product_category.c_id=2) 
or (product_category.c_id=8) 

Che ora è distinto ma non mostra informazioni sufficienti sul prodotto o sulla categoria. Voglio mostrare quante più informazioni possibili in ogni riga.

E il passo successivo è quello di ottenere solo quelli in cui l'shop.s_id = 1 o shop.s_id = 2.

Qualcuno può aiutarmi a ottenere lì o avvicino? Grazie!

+0

prova 'SELECT DISTINCT *' o 'SELEZIONARE col1 DISTINTO, col2 ...' –

risposta

2

Supponiamo che vogliate elencare tutte le informazioni sul prodotto. Se non desideri che i prodotti vengano ripetuti, puoi utilizzare la clausola IN.

select p.* 
from product p 
where p.p_id in (select c.p_id from product_category c where c.c_id in (2,8)) 
    and p.p_id in (select s.p_id from product_shop s where s.s_id in (1,2)) 

Ora, se si desidera che tutti i dati di prodotto e lista che le categorie e negozi il prodotto è correlato a, allora si può usare aderire e alcune funzioni molto a portata di mano.

select p.p_id, p.`name`, p.brand, GROUP_CONCAT(DISTINCT c.c_id SEPARATOR ', ') as categories, GROUP_CONCAT(DISTINCT s.s_id SEPARATOR ', ') as shops 
from product p inner join product_category c on p.p_id = c.p_id 
       inner join product_shop s on p.p_id = s.p_id 
where c.c_id in (2,8) 
    and s.s_id in (1,2) 
group by p.p_id, p.`name`, p.brand 
+0

Grazie! Per qualche ragione lo visualizza nella riga dei risultati di un prodotto, per categorie e negozi: 2, 8, 8, 2 1, 2, 1, 2' es. Ha negozi e categorie duplicati per un prodotto. Ho pubblicato una foto delle voci nella mia tabella product_category ... Sto facendo qualcosa di sbagliato lì, cioè facendo duplicare le categorie di un singolo prodotto e i negozi? – BeniaminoBaggins

+0

Ciò accade perché il prodotto è presente in 2 negozi ed è correlato a 2 categorie: 2 x 2 = 4 occorrenze del prodotto. La soluzione è aggiungere distinti su group_concat. Vedi la mia modifica sulla risposta. –