usthere's Blog
5set/090

GROUP_CONCAT tips 2 – il ritorno

un modo produttivo per usare i group_concat è creare delle views specifiche avendo così tutti i dati in un unica "tabella", ma come fare per fare delle select sui valori ritornati da group_concat?
il campo è considerato varchar fino al valore di group_concat_max_len è maggiore di 512, altrimenti è considerato BLOB, quindi si può usare una clausola where in questo modo:

select * from vestiti
where (taglie like 'l' or taglie like '%,l,%' or taglie like '%,l' or taglie like 'l,%' ) and (colori like 'rosso' or colori like '%,rosso,%' or colori like '%,rosso' or colori like 'rosso,%' )

p.s.
vestiti è la nostra view, in questo caso specifico voglio avere tutti i vestiti che hanno taglia L e colore rosso

2set/090

GROUP_CONCAT tips

l'altro giorno mi sono imbattuto in un piccolo "problema" di visualizzazione di risultati di una query..
in particolare, cosa succede quando ho una relazione molti a molti su due tabelle? in generale si crea una tabella "intermediario"
nella quale si gestiscono le varie relazioni.. è qui che sorge il "problema" e cioè: normalmente cosa succede quando si fa una select?
i risultati vengono spianati su varie righe, proprio perchè (per definizione) ad un record della tabella 1
corrispondono più record della tabella 2!
ma vediamo in particolare con un esempio come funziona questa comoda funzione (non standard)
le tabelle saranno:

CREATE TABLE `prodotti` (
`ID` int(10) unsigned NOT NULL auto_increment,
`nome` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

CREATE TABLE `valori_attributo` (
`ID` int(10) unsigned NOT NULL auto_increment,
`valore` varchar(255) NOT NULL,
`tipo` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

CREATE TABLE `valori_prodotti` (
`ID` int(10) unsigned NOT NULL auto_increment,
`ID_prodotto` int(10) unsigned NOT NULL default '0',
`ID_valore_attributo` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

popoliamo un pò il db:

insert into valori_attributo values (NULL,'rosso','colore'),(NULL,'blu','colore'),(NULL,'verde','colore'),(NULL,'giallo','colore'),(NULL,'M','taglia'),(NULL,'S','taglia'),(NULL,'L','taglia'),(NULL,'XL','taglia')

insert into prodotti values (NULL,'maglia corta'),(NULL,'maglia maniche lunghe'),(NULL,'pullover')

insert into valori_prodotti values (NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'XL')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'S')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'L')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'rosso')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'blu')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'verde')),(NULL,(select ID from prodotti where nome = 'maglia corta'),(select ID from valori_attributo where valore = 'giallo')),(NULL,(select ID from prodotti where nome = 'maglia corta'),(select ID from valori_attributo where valore = 'M'))

in questo esempio se avessimo voluto tutti i prodotti con a lato i relativi valori attributo la cosa più naturale da scrivere
sarebbe qualcosa del tipo:

select (select nome from prodotti where ID = ID_prodotto) as prodotto,(select valore from valori_attributo where ID = ID_valore_attributo) as valore from valori_prodotti

che produce un risultato simile a questo:

prodotto valore
pullover XL
pullover S
pullover L
pullover rosso
pullover blu
pullover verde
maglia corta giallo
maglia corta M

mentre con questa bellissima istruzione:

select prodotti.nome, GROUP_CONCAT(DISTINCT (select valore from valori_attributo where valori_prodotti.ID_valore_attributo = valori_attributo.ID and valori_attributo.tipo = 'colore') SEPARATOR ',') as colore, GROUP_CONCAT(DISTINCT (select valore from valori_attributo where valori_prodotti.ID_valore_attributo = valori_attributo.ID and valori_attributo.tipo = 'taglia') SEPARATOR ',') as taglie from valori_prodotti,prodotti
where valori_prodotti.ID_prodotto = prodotti.ID group by prodotti.ID

avremo questo risultato:

nome colore taglie
maglia corta giallo M
pullover rosso,blu,verde XL,S,L

carino no? :)