2012-07-14 10 views
7

Estoy trabajando en un proyecto de código abierto llamado PHP-Bouncer, y estoy teniendo problemas con una consulta de MySQL. Estoy escribiendo para ello. Básicamente tenemos tres tablas: BouncerRoles, PageInRole y BouncerPageOverrides. BouncerRoles contiene niveles de acceso, y las otras dos tablas vinculan a BouncerRoles a través de Foreign Key y proporcionan múltiples entradas de datos adicionales. He escrito la siguiente consulta para intentar tirar de todos los datos papel que tenga a la vez:MySQL Group_Concat Repetir valores

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; 

El objetivo de esta consulta es proporcionar al RoleID, NombreRol, una lista delimitada por la tubería de páginas previstas, y una lista delimitada por tuberías de sustituciones (en la forma de una página reemplazada & reemplazando página). Todo funciona excepto la última columna de la consulta, que repite las entradas que encuentra una y otra vez como esto (salida en 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 

¿hay algo que he hecho mal en mi consulta para causar esto?

+1

Mente que 'GROUP_CONCAT' puede ser un dolor en el culo si tiene un gran resultado -> sólo se devuelve un resultado tamaño limitado (creo que 1024 bytes, pero no estoy seguro), así que si su conjunto de resultados es más grande se cortará. – Nanne

+3

¿Te estás perdiendo un 'DISTINCT' dentro de tu' GROUP_CONCAT'? Parece que su unión está devolviendo varias filas. –

+1

@nanne: Ese límite (1024) depende de una configuración. Puede ser alargado. –

Respuesta

21

Probablemente se está uniendo a una tabla con dos tablas en las relaciones 1..n, produciendo resultados duplicados.

  • utilizar cualquiera GROUP_CONCAT(DISTINCT ...) o

  • Uso dos subconsultas: en cada uno de los usos GROUP_CONCAT() con el grupo por cada una de las 2 tablas. Luego une las dos subconsultas y la tabla principal.

+0

Adding Distinct en el segundo group_concat did el truco ... ¡Gracias! –

+0

¿No hay otra opción? Al igual que con un conjunto de datos grande (en mi caso) las subconsultas son extremadamente lentas pero no puedo usar distintas porque necesito que cada valor sea devuelto aunque sea el mismo .. –

+0

@ ThomasClowes: puede publicar una pregunta. No olvide incluir la consulta real, las definiciones de las tablas (incluidos los índices) y el plan de ejecución. También puede publicar la pregunta en [http://dba.stackexchange.com/] (http://dba.stackexchange.com/) donde puede mejorar en Tention. –