2011-06-30 89 views
7

He estado tratando de volver a hacer esta afirmación, pero fue en vano.SQL SUM y CASE y DISTINCT

SELECT b.Program AS Program, 
    SUM(CASE WHEN a.Gender LIKE 'M%' THEN 1 ELSE NULL END) AS Males,  
    SUM(CASE WHEN a.Gender LIKE 'F%' THEN 1 ELSE NULL END) AS Females, 
    SUM(CASE WHEN e.Activity LIKE 'Arts' THEN 1 ELSE NULL END) AS Arts, 
    AVG(CASE WHEN a.Gender LIKE 'M%' THEN CAST(f.Score AS DEC(10,2)) ELSE NULL END) 
AS MalesAverage 
FROM tblChildren a 
    LEFT JOIN tblInvolvement b ON b.ChildID = a.ChildID 
    LEFT JOIN tblActivities e ON e.ChildID = b.ChildID 
    LEFT JOIN tblScores f ON f.ChildID = b.ChildID 
WHERE b.Place = 'Location' 
    AND b.Program = 'Program' 
    AND b.Year = '2009-10' 
    AND f.Assessment LIKE '%Pre%Assessment%' 
    AND e.StudentID = b.StudentID 
GROUP BY Program 

Ahora voy a obtener resultados como:

Program Males Females Arts MalesAverage 
--------------------------------------- 
Program 7  5  1 50.000000 

El problema con esto es que sólo hay 4 hombres y 3 mujeres, y que cuando agrego los tblActivites, parece dar duplicados. Después de revisar, noté que había 12 ChildID en la tabla de Actividades, porque los Niños estaban vinculados a más de una actividad. Traté de usar algo como:

SELECT SUM(DISTINCT CASE WHEN a.Gender LIKE 'M%' THEN 1 ELSE NULL END) AS Males 

Sin embargo, acaba de regresar 1 en la columna de los hombres. Cualquier ayuda sería apreciada. Y solo para aclarar más, las tablas están unidas mediante ChildID, solo necesito ayuda para asegurarme de que estoy devolviendo la información correcta. Si esto se resuelve, mi lista masiva de estas cosas se resolverá. Es preferible evitar GROUP BY para todo, ya que tengo muchos datos.

+0

@niktrs Como se explica en la respuesta a continuación que aún da 7 hombres, cuando los resultados adecuados deberían ser 4. – jnewkirk

+0

compruebe las relaciones entre la tabla y las uniones. Ejecuta la consulta sin los agregados y verifica el resultado por algo extraño. – niktrs

Respuesta

11

¿Funcionaría?

COUNT(DISTINCT CASE WHEN a.Gender LIKE 'M%' THEN a.ChildID ELSE NULL END) AS Males 

sospecho que hay mejores maneras de hacer la unión en general, pero sin saber mucho más sobre el esquema que realmente no lo sé.

+0

Qué es exactamente lo que necesita saber. Puedo dar más nombres genéricos de lo que realmente veo, ya que estos ya son genéricos, no son nombres de tablas reales. – jnewkirk

+0

Empezaría con, ¿cuáles son las claves principales de esas tablas? Pero creo que la expresión COUNT que di se dirigirá a tu problema inmediato. –

+0

Esto funciona, sin embargo, también podría necesitar alguna aclaración para la función agregada de AVG, pero agradezco mucho su ayuda. – jnewkirk

0

No muestra los datos de origen, pero estoy dispuesto a apostar que tiene varias filas por persona por programa.

Usted GROUP BY Program que agrega por programa, pero si por ejemplo John Smith tiene dos filas con ese programa de identificación, que va a ser contados como MALE dos veces.

Por favor, muéstrenos la estructura de su tabla para que podamos darle una consulta más clara. Idealmente obtendrá el recuento de una subselección usando un GROUP BY en algo como Person_ID para que no obtenga recuentos duplicados.

+0

Esto es lo que estaba tratando de evitar. El programa no es el problema, sin embargo. "Después de revisar, noté que había 12 ChildID en la tabla de actividades, porque los niños estaban vinculados a más de una actividad". Como indiqué, este es el problema, el niño está vinculado a más de una actividad a la vez produciendo ChildID idénticos en las actividades tbl que tiene 2 columnas. ChildID y actividad. Sin embargo, me gustaría tratar de evitar GROUP BY, pero si es inevitable, entonces creo que puedo hacerlo. – jnewkirk