2012-07-14 17 views
7

Sto lavorando a un progetto open source chiamato PHP-Bouncer e sto riscontrando problemi con una query MySQL che sto scrivendo per questo. Fondamentalmente abbiamo tre tabelle: BouncerRoles, PageInRole e BouncerPageOverrides. BouncerRoles contiene livelli di accesso e le altre due tabelle rimandano a BouncerRoles tramite Chiave esterna e forniscono più voci di dati aggiuntivi. Ho scritto la seguente query per tentare di tirare tutti i dati del ruolo ho bisogno di tutti in una volta:MySQL Group_Concat Valori ripetuti

select BouncerRoles.RoleID, BouncerRoles.RoleName, 
GROUP_CONCAT(PageInRole.PageName separator '|') as ProvidedPages, 
GROUP_CONCAT(CONCAT(BouncerPageOverrides.OverriddenPage,'&',BouncerPageOverrides.OverridingPage) separator '|') as OverriddenPages 
from BouncerRoles join PageInRole on BouncerRoles.RoleID = PageInRole.RoleID 
join BouncerPageOverrides on BouncerRoles.RoleID = BouncerPageOverrides.RoleID 
group by BouncerRoles.RoleID; 

L'obiettivo di questa ricerca è quello di fornire l'ID ruolo, RoleName, un tubo elenco delimitato di pagine previste, e un elenco delimitato da pipe di sovrascritture (sotto forma di override page & overridingpage). Tutto funziona tranne l'ultima colonna della query, che ripete le voci che trova più e più volte come questo (in uscita in formato CSV):

RoleID,RoleName,ProvidedPages,OverriddenPages 
2,Exchange,exchange-how.php|exchange-support.php|exchange.php|premium-promo.php|exchange-resorts.php|premiumplus-promo.php|exchange-deposit.php|exchange-requestdestination.php,whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php|whyexchange.php&exhange.php 
3,Premium,premiumplus-promo.php|premium-cruises.php|premium-resorts.php|premium-condohome.php|premium-hotelaircar.php|premium.php|premium-restaurants.php|premium-overview.php,premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php|premium-promo.php&premium.php 
4,"Premium Plus",premiumplus-exclusiveescapes.php|premiumplus.php|premiumplus-overview.php|premiumplus-concierge.php|premiumplus-airportlounge.php,premiumplus-promo.php&premiumplus.php|premiumplus-promo.php&premiumplus.php|premiumplus-promo.php&premiumplus.php|premiumplus-promo.php&premiumplus.php|premiumplus-promo.php&premiumplus.php 

c'è qualcosa che ho fatto di sbagliato nella mia query per causare questo?

+1

Ricordate che 'GROUP_CONCAT' può essere un dolore nel culo se si dispone di un grande risultato -> verrà restituito solo il risultato limitate dimensioni (credo 1024 byte, ma non sono sicuro), quindi se il vostro gruppo di risultati è più grande sarà tagliato fuori. – Nanne

+3

Ti manca un 'DISTINCT' all'interno del tuo 'GROUP_CONCAT'? Sembra che il tuo join restituisca più righe. –

+1

@nanne: quel limite (1024) dipende da un'impostazione. Può essere allungato. –

risposta

21

Probabilmente stai unendo una tabella con due tabelle sulle relazioni 1..n, producendo risultati duplicati.

  • utilizzare uno o GROUP_CONCAT(DISTINCT ...)

  • Uso due sottointerrogazioni: in ognuna uso GROUP_CONCAT() con il gruppo da su ciascuno dei 2 tavoli. Quindi unire le due subquery e la tabella principale.

+0

L'aggiunta di Distinto al secondo group_concat ha fatto il trucco ... Grazie! –

+0

Non c'è altra opzione? Come con un set di dati di grandi dimensioni (nel mio caso) le sottoquery sono estremamente lente, ma non posso usare distinte perché ho bisogno di ogni valore restituito anche se è lo stesso .. –

+0

@ ThomasClowes Puoi pubblicare una domanda, quindi non dimenticare di includere la query effettiva, le definizioni delle tabelle (compresi gli indici) e il piano di esecuzione. Puoi anche pubblicare la domanda su [http://dba.stackexchange.com/] (http://dba.stackexchange.com/) dove potrebbe migliorare tenzione. –

Problemi correlati