sacar porcentajes porcentaje iva descuento datos campo calcular aplicar sql sql-server tsql

porcentajes - Cómo calcular el porcentaje con una declaración de SQL



porcentajes en postgresql (11)

Tengo una tabla de SQL Server que contiene usuarios y sus calificaciones. En aras de la simplicidad, digamos que hay 2 columnas: name y grade . Entonces una fila típica sería Nombre: "John Doe", Grado: "A".

Estoy buscando una declaración de SQL que encuentre los porcentajes de todas las respuestas posibles. (A, B, C, etc.). Además, ¿hay alguna manera de hacerlo sin definir todas las respuestas posibles (campo de texto abierto - los usuarios pueden ingresar ''aprobado / suspendido'', ''ninguno'', etc. ...)

El resultado final que estoy buscando es A: 5%, B: 15%, C: 40%, etc.


  1. El más eficiente (usando más de ()).

    select Grade, count(*) * 100.0 / sum(count(*)) over() from MyTable group by Grade

  2. Universal (cualquier versión de SQL).

    select Rate, count(*) * 100.0 / (select count(*) from MyTable) from MyTable group by Rate;

  3. Con CTE, el menos eficiente.

    with t(Rate, RateCount) as ( select Rate, count(*) from MyTable group by Rate ) select Rate, RateCount * 100.0/(select sum(RateCount) from t) from t;


Creo que esta es una solución general, aunque la probé utilizando IBM Informix Dynamic Server 11.50.FC3. La siguiente consulta:

SELECT grade, ROUND(100.0 * grade_sum / (SELECT COUNT(*) FROM grades), 2) AS pct_of_grades FROM (SELECT grade, COUNT(*) AS grade_sum FROM grades GROUP BY grade ) ORDER BY grade;

da la siguiente salida en los datos de prueba que se muestran debajo de la regla horizontal. La función ROUND puede ser específica de DBMS, pero el resto (probablemente) no. (Tenga en cuenta que modifiqué 100 a 100.0 para asegurarme de que el cálculo se realiza utilizando valores no enteros - DECIMAL, NUMERIC - aritmética; vea los comentarios y gracias a Thunder.)

grade pct_of_grades CHAR(1) DECIMAL(32,2) A 32.26 B 16.13 C 12.90 D 12.90 E 9.68 F 16.13

CREATE TABLE grades ( id VARCHAR(10) NOT NULL, grade CHAR(1) NOT NULL CHECK (grade MATCHES ''[ABCDEF]'') ); INSERT INTO grades VALUES(''1001'', ''A''); INSERT INTO grades VALUES(''1002'', ''B''); INSERT INTO grades VALUES(''1003'', ''F''); INSERT INTO grades VALUES(''1004'', ''C''); INSERT INTO grades VALUES(''1005'', ''D''); INSERT INTO grades VALUES(''1006'', ''A''); INSERT INTO grades VALUES(''1007'', ''F''); INSERT INTO grades VALUES(''1008'', ''C''); INSERT INTO grades VALUES(''1009'', ''A''); INSERT INTO grades VALUES(''1010'', ''E''); INSERT INTO grades VALUES(''1001'', ''A''); INSERT INTO grades VALUES(''1012'', ''F''); INSERT INTO grades VALUES(''1013'', ''D''); INSERT INTO grades VALUES(''1014'', ''B''); INSERT INTO grades VALUES(''1015'', ''E''); INSERT INTO grades VALUES(''1016'', ''A''); INSERT INTO grades VALUES(''1017'', ''F''); INSERT INTO grades VALUES(''1018'', ''B''); INSERT INTO grades VALUES(''1019'', ''C''); INSERT INTO grades VALUES(''1020'', ''A''); INSERT INTO grades VALUES(''1021'', ''A''); INSERT INTO grades VALUES(''1022'', ''E''); INSERT INTO grades VALUES(''1023'', ''D''); INSERT INTO grades VALUES(''1024'', ''B''); INSERT INTO grades VALUES(''1025'', ''A''); INSERT INTO grades VALUES(''1026'', ''A''); INSERT INTO grades VALUES(''1027'', ''D''); INSERT INTO grades VALUES(''1028'', ''B''); INSERT INTO grades VALUES(''1029'', ''A''); INSERT INTO grades VALUES(''1030'', ''C''); INSERT INTO grades VALUES(''1031'', ''F'');


En cualquier versión de servidor sql puede usar una variable para el total de todos los grados como este:

declare @countOfAll decimal(18, 4) select @countOfAll = COUNT(*) from Grades select Grade, COUNT(*) / @countOfAll * 100 from Grades group by Grade


En lugar de usar un CTE por separado para obtener el total, puede usar una función de ventana sin la cláusula "partición por".

Si estás usando:

count(*)

Para obtener el conteo de un grupo, puede usar:

sum(count(*)) over ()

para obtener la cuenta total

Por ejemplo:

select Grade, 100. * count(*) / sum(count(*)) over () from table group by Grade;

En mi experiencia, tiende a ser más rápido, pero creo que podría usarse internamente una tabla temporal en algunos casos (he visto "Tabla de trabajo" cuando se ejecuta con "establecer estadísticas io en").

EDITAR: No estoy seguro si mi consulta de ejemplo es lo que está buscando, solo estaba ilustrando cómo funcionan las funciones de ventana.


He probado lo siguiente y esto funciona. La respuesta de gordyii estaba cerca pero tenía la multiplicación de 100 en el lugar equivocado y tenía algunos paréntesis faltantes.

Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score From MyTable Group By Grade


Lo siguiente debería funcionar

ID - Key Grade - A,B,C,D...

EDITAR: movió el * 100 y agregó el 1.0 para asegurarse de que no haga división entera

Select Grade, Count(ID) * 100.0 / ((Select Count(ID) From MyTable) * 1.0) From MyTable Group By Grade


Necesita agrupar en el campo de calificación. Esta consulta debería darle lo que busca en prácticamente cualquier base de datos.

Select Grade, CountofGrade / sum(CountofGrade) *100 from ( Select Grade, Count(*) as CountofGrade From Grades Group By Grade) as sub Group by Grade

Debe especificar el sistema que está usando.


Puede usar una subselección en su consulta de (no comprobado y no está seguro, que es más rápido):

SELECT Grade, COUNT(*) / TotalRows FROM (SELECT Grade, COUNT(*) As TotalRows FROM myTable) Grades GROUP BY Grade, TotalRows

O

SELECT Grade, SUM(PartialCount) FROM (SELECT Grade, 1/COUNT(*) AS PartialCount FROM myTable) Grades GROUP BY Grade

O

SELECT Grade, GradeCount / SUM(GradeCount) FROM (SELECT Grade, COUNT(*) As GradeCount FROM myTable GROUP BY Grade) Grades

También puede usar un procedimiento almacenado (disculpas por la sintaxis de Firebird):

SELECT COUNT(*) FROM myTable INTO :TotalCount; FOR SELECT Grade, COUNT(*) FROM myTable GROUP BY Grade INTO :Grade, :GradeCount DO BEGIN Percent = :GradeCount / :TotalCount; SUSPEND; END


Simplemente uso esto cuando necesito calcular un porcentaje.

ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage

Tenga en cuenta que 100.0 devuelve decimales, mientras que 100 por sí solo redondeará el resultado al número entero más cercano, incluso con la función ROUND ().


Tienes que calcular el total de calificaciones Si es SQL 2005 puedes usar CTE

WITH Tot(Total) ( SELECT COUNT(*) FROM table ) SELECT Grade, COUNT(*) / Total * 100 --, CONVERT(VARCHAR, COUNT(*) / Total * 100) + ''%'' -- With percentage sign --, CONVERT(VARCHAR, ROUND(COUNT(*) / Total * 100, -2)) + ''%'' -- With Round FROM table GROUP BY Grade


SELECT Grade, GradeCount / SUM(GradeCount) FROM (SELECT Grade, COUNT(*) As GradeCount FROM myTable GROUP BY Grade) Grades