Digamos que tengo una base de datos de la columna «grado» como este:

|grade|
|    1|
|    2|
|    1|
|    3|
|    4|
|    5|

Hay no trivial de la forma en SQL para generar un histograma como este?

|2,1,1,1,1,0|

donde 2 significa que el grado 1 se produce dos veces, el medio 1s grados {2..5} ocurren una vez y 0 de 6 ° grado no se produce en absoluto.

No me importa si el histograma es una fila por cada cuenta.

Si que importa, la base de datos es SQL Server accede por un perl CGI a través de unixODBC/FreeTDS.

EDICIÓN: Gracias por tus rápidas respuestas! Está bien si no los valores existentes (como el grado 6 en el ejemplo anterior) no se producen como puedo hacer que histograma valor pertenece a qué grado.

OriginalEl autor Thorsten79 | 2009-01-27

7 Comentarios

  1. 28
    SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade

    No lo he verificado, pero debería funcionar.No será, sin embargo, cuenta de demostración para 6s grado, ya que no se presentan en la tabla a todos…

    OriginalEl autor Ilya Volodin

  2. 6

    Utilizar una tabla temporal para obtener su falta de valores:

    CREATE TABLE #tmp(num int)
    DECLARE @num int
    SET @num = 0
    WHILE @num < 10
    BEGIN
      INSERT #tmp @num
      SET @num = @num + 1
    END
    
    
    SELECT t.num as [Grade], count(g.Grade) FROM gradeTable g
    RIGHT JOIN #tmp t on g.Grade = t.num
    GROUP by t.num
    ORDER BY 1
    Mejor: Generar la tabla de identidad a través de select top 10 identity(int, 1, 1) as num into #tmp from sysobjects, sys.all_colums

    OriginalEl autor cjk

  3. 4

    Si hay una gran cantidad de puntos de datos, también puede el grupo de los rangos juntos como este:

    SELECT FLOOR(grade/5.00)*5 As Grade, 
           COUNT(*) AS [Grade Count]
    FROM TableName
    GROUP BY FLOOR(Grade/5.00)*5
    ORDER BY 1

    Además, si quería etiqueta de la gama completa, usted puede conseguir el piso y el techo antes de tiempo con una CTE.

    With GradeRanges As (
      SELECT FLOOR(Score/5.00)*5     As GradeFloor, 
             FLOOR(Score/5.00)*5 + 4 As GradeCeiling
      FROM TableName
    )
    SELECT GradeFloor,
           CONCAT(GradeFloor, ' to ', GradeCeiling) AS GradeRange,
           COUNT(*) AS [Grade Count]
    FROM GradeRanges
    GROUP BY GradeFloor, CONCAT(GradeFloor, ' to ', GradeCeiling)
    ORDER BY GradeFloor

    Nota: En algunos motores SQL, usted puede GROUP BY un Ordinal Índice de Columna, pero con MS SQL, si lo quieres en el SELECT declaración, usted va a necesitar para el grupo por ella también, por lo tanto la copia de la Gama en el Grupo de Expresión así.

    Opción 2: Se puede usar el caso de las declaraciones selectivamente los valores de recuento en arbitraria contenedores y, a continuación, unpivot ellos para obtener una fila por fila recuento de valores

    Esta es también una herramienta valiosa para valores continuos como los valores con decimales, tales como una cantidad de dinero, o un grupo de valores que representan una lista de los promedios.

    OriginalEl autor KyleMit

  4. 3

    Gamecat del uso de los DISTINTOS parece un poco raro para mí, tendrá que probarlo cuando estoy de vuelta en la oficina…

    La manera en que yo haria es similar, aunque…

    SELECT
        [table].grade        AS [grade],
        COUNT(*)             AS [occurances]
    FROM
        [table]
    GROUP BY
        [table].grade
    ORDER BY
        [table].grade

    Para superar la falta de datos donde hay 0 ocurrencias, usted puede UNIRSE a una tabla que contiene válidos todos los grados. El COUNT(*) se tendrá en cuenta los valores NULOS, pero COUNT(grado) no cuenta los valores NULOS.

    DECLARE @grades TABLE (
       val INT
       )  
    
    INSERT INTO @grades VALUES (1)  
    INSERT INTO @grades VALUES (2)  
    INSERT INTO @grades VALUES (3)  
    INSERT INTO @grades VALUES (4)  
    INSERT INTO @grades VALUES (5)  
    INSERT INTO @grades VALUES (6)  
    
    SELECT
        [grades].val         AS [grade],
        COUNT([table].grade) AS [occurances]
    FROM
        @grades   AS [grades]
    LEFT JOIN
        [table]
            ON [table].grade = [grades].val
    GROUP BY
        [grades].val
    ORDER BY
        [grades].val
    Sí, yo estaba equivocado. Y se perdió en el grupo. SQL a rusty error.

    OriginalEl autor MatBailie

  5. 2
    select Grade, count(Grade)
    from MyTable
    group by Grade

    OriginalEl autor Seibar

  6. 2

    Según Shlomo Priymak del artículo Cómo Crear Rápidamente un Histograma en MySQL, usted puede utilizar la siguiente consulta:

    SELECT grade, 
           COUNT(\*) AS 'Count',
           RPAD('', COUNT(\*), '*') AS 'Bar' 
    FROM grades 
    GROUP BY grade

    Que va a producir la siguiente tabla:

    grade   Count   Bar
    1       2       **
    2       1       *
    3       1       *
    4       1       *
    5       1       *

    OriginalEl autor devon

  7. 0

    Estoy construyendo sobre lo que Ilya Volodin hicimos anteriormente, que debe permitir a usted para seleccionar un rango de grado que desea agrupar en su resultado:

    DECLARE @cnt INT = 0;
    
    WHILE @cnt < 100 -- Set max value
    BEGIN
    SELECT @cnt,COUNT(fe) FROM dbo.GEODATA_CB where fe >= @cnt-0.999 and fe <= @cnt+0.999 -- set tolerance
    SET @cnt = @cnt + 1; -- set step
    END;

    OriginalEl autor Sylvain Ayrault

Dejar respuesta

Please enter your comment!
Please enter your name here