Estoy trabajando en una tabla dinámica de consulta.
El esquema es el siguiente

Sno, Nombre, Distrito

El mismo nombre puede aparecer en muchos distritos por ejemplo tomar la muestra de datos, por ejemplo

1 Mike CA
2 Mike CA
3 Proctor JB
4 Luke MN
5 Luke MN
6 Mike CA
7 Mike LP
8 Proctor MN
9 Proctor JB
10 Proctor MN
11 Luke MN

Como veis que yo tengo un juego de 4 distritos distintos (CA, JB, MN, LP). Ahora quería obtener la tabla dinámica generada por la asignación de los nombres de los distritos

Name CA JB MN LP
Mike 3 0 0 1
Proctor 0 2 2 0
Luke 0 0 3 0

me escribió la siguiente consulta para este

select name,sum(if(District="CA",1,0)) as "CA",sum(if(District="JB",1,0)) as "JB",sum(if(District="MN",1,0)) as "MN",sum(if(District="LP",1,0)) as "LP" from district_details group by name

Sin embargo, existe la posibilidad de que los distritos pueden aumentar, en ese caso voy a tener que editar manualmente la consulta de nuevo y añadir el nuevo distrito a ella.

Quiero saber si hay una consulta que pueden tomar los nombres de los distintos distritos y ejecutar la consulta anterior. Sé que puedo hacerlo con un procedimiento y la generación de la secuencia de comandos sobre la marcha, ¿hay algún otro método también?

Pido así porque la salida de la consulta «select distinct(distritos) de district_details» volverá a mí de una sola columna con el nombre de distrito en cada fila, lo que me gustaría ser transpuesta a la columna.

  • Echa un vistazo a mysql GROUP_CONCAT() función.
InformationsquelleAutor Anirudh Goel | 2009-10-21

4 Comentarios

  1. 3

    Usted simplemente no puede tener una estática instrucción SQL devuelve un número variable de columnas. Usted necesita para construir dicha declaración cada vez que el número de distritos diferentes cambios. Para ello se debe ejecutar primero un

    SELECT DISTINCT District FROM district_details;

    Esto le dará la lista de los distritos donde hay más detalles. A continuación, se genera una instrucción SQL iterando sobre el resultado anterior (pseudocódigo)

    statement = "SELECT name "
    
    For each row returned in d = SELECT DISTINCT District FROM district_details 
        statement = statement & ", SUM(IF(District=""" & d.District & """,1 ,0)) AS """ & d.District & """" 
    
    statement = statement & " FROM district_details GROUP BY name;"

    Y ejecutar esa consulta. A continuación, debe tener para manejar en su código el procesamiento de la variable número de columnas

  2. 1

    a) «Para cada» no es compatible con MySQL procedimientos almacenados.
    b) los procedimientos Almacenados no se pueden ejecutar sentencias preparadas de cadenas concatenadas mediante la llamada sentencias SQL dinámicas, ni puede devolver resultados con más de Una fila distinto.
    c) que se Almacenan funciones no puede ejecutar SQL dinámico en todo.

    Es una pesadilla para seguir la pista de una vez que tienes una buena idea y todo el mundo parece refutar que, antes de pensar en «¿por Qué alguien quiere…»

    Espero que usted encuentre la solución, todavía estoy buscando la mía.
    La cierra que me dieron fue

    (excusa el pseudo código)

    -> a procedimiento almacenado, construir la función que…

    1) crear la tabla temporal
    2) carga de datos en la tabla temporal de columnas con sus declaraciones y si
    3) carga de la tabla temporal a INOUT o FUERA de los parámetros de un procedimiento almacenado que sería una tabla llamada… SI se puede conseguir a devolver más de una fila

    También otro consejo…
    Almacenar sus distritos, como una mesa de estilo convencional, la carga de este y recorrer con un bucle a través de los distritos de la marca como activo de forma dinámica concatenar una cadena de consulta que puede ser texto sin formato para que todo el sistema se preocupa

    A continuación, utilice;

    preparar stmName de @yourqyerstring;
    ejecutar stmName;
    desasignar preparar stmName;

    (encontrar mucho más en los procedimientos almacenados parte de mysql, el foro también)

    para ejecutar un conjunto diferente de los distritos de cada momento, sin tener que re-diseño de su original proc

    Tal vez es más fácil en forma numérica.
    Yo trabajo en la llanura de contenido de texto en las tablas y no tienen nada que sumar, contar o sumar

    • «b) los procedimientos Almacenados no se pueden ejecutar sentencias preparadas de cadenas concatenadas mediante la llamada sentencias SQL dinámicas, ni puede devolver resultados con más de Una fila distinto. c) que se Almacenan funciones no puede ejecutar SQL dinámico en todos.» Lo que es falso. MySQL procedimientos almacenados pueden ejecutar SQL dinámico, también pueden ser concatenadas y preparado, pero no pueden estar anidados (es decir, no puede ejecutar otra preparación y EJECUCIÓN instrucción EXECUTE). Ver: dev.mysql.com/doc/refman/5.0/en/…
    • «a) «Para cada» no es compatible con MySQL procedimientos almacenados.» Si bien es cierto, el bucle está disponible dentro de MySQL SP con REPEAT-UNTIL/BUCLE. Ver: dev.mysql.com/doc/refman/5.0/en/repeat-statement.html
    • Tengo que decir que a pesar de mis comentarios anteriores, yo soy parcial: yo no creo en SPs y condeno su uso. Msf está mal, a menos que sea estrictamente necesario y de todas las otras alternativas (como código + caché) han demostrado ser peor.
  3. 0

    La siguiente asume que quieren los partidos de distinta (nombre/distrito) pares. I. e. Lucas/CA y el Duque/CA daría dos resultados:

    SELECT name, District, count(District) AS count
    FROM district_details
    GROUP BY District, name

    Si este no es el caso, simplemente quitar el nombre de la cláusula GROUP BY.

    Por último, observe que cambié suma() para count() como usted está tratando de contar todas las filas agrupadas en lugar de obtener una suma de valores.

    • gracias por tu aporte, sin embargo no es lo que yo quiero. Quiero mostrar el distrito recuento de todos los nombres en todos los distritos. Así que si por Lucas o Duke,yo quiero tener a su cargo para cada distrito, 0 si no existe para ese distrito. También se suma 1 a n veces (que yo estoy haciendo en la consulta) hace la misma cosa en la que creo.
  4. 0

    A través de comentario por @cballou arriba, yo era capaz de realizar este tipo de función que no es exactamente lo OP pidió pero se ajustaba a mi situación similar, por lo que agregar aquí para ayudar a los que vienen después.

    Normal de la instrucción select:

    SELECT d.id ID,
           q.field field,
           q.quota quota
      FROM defaults d
      JOIN quotas q ON d.id=q.default_id

    Vertical de resultados:

    ID field  quota
    1  male   25
    1  female 25
    2  male   50

    Instrucción Select utilizando group_concat:

    SELECT d.id ID,
           GROUP_CONCAT(q.fields SEPARATOR ",") fields,
           GROUP_CONCAT(q.quotas SEPARATOR ",") quotas
      FROM defaults d
      JOIN quotas q ON d.id=q.default_id

    Yo campos separados por comas de los «campos» y «cuotas» que luego se pueden procesar fácilmente mediante programación más tarde.

    Horizontal resultados:

    ID fields      quotas
    1  male,female 25,25
    2  male        50

    Magia!

Dejar respuesta

Please enter your comment!
Please enter your name here