Tengo una tabla con registros que tienen algunas propiedades. Una de las propiedades es su estado.

También tengo una visión que cuenta y agrupa a los estados. Se parece a esto:

State        Total

Canceled     9
Failed       3
Pending      10
Succeeded    7

Como no hay ningún registro con el estado 'Procesando' en mi tabla de referencia, la vista no lo muestra en la vista. Sin embargo, quiero cada uno de los cinco estados posibles en mi opinión, incluso si no existe en la tabla.

Hice la siguiente consulta y estoy cerca de hacerlo funcionar (probándolo con uno de los estados disponibles):

SELECT State, COUNT(State) AS Total
FROM dbo.Job
GROUP BY State
UNION
SELECT 'Processing' AS State, 0 AS Total

El problema es mi '0 AS Total'. El 0 debe ser dinámico. ¿Hay alguna forma de reemplazarlo?

sql
1
Bryan 10 sep. 2018 a las 17:50

5 respuestas

La mejor respuesta

Para obtener una lista completa de State, todos los valores deben provenir de otro lugar que no sea su conjunto de datos inicial (suponiendo que no todos los valores estén representados, como es el caso actual con 'Procesando'). Esa puede ser una tabla, que es su mejor opción si tiene los privilegios para crear dicha tabla o, si es necesario, de una lista, que luego deberá mantener si se agregan nuevos valores State .

En el segundo caso, un constructor de valores de tabla hará el trabajo por usted. Comience con ese constructor, luego LEFT JOIN a su fuente de datos. Una INNER JOIN, nuevamente, filtrará los valores que faltan en sus datos subyacentes.

SELECT
  s.[State]
 ,COUNT(j.[State]) AS Total
FROM
    (
      VALUES
        ('Canceled')
       ,('Failed')
       ,('Pending')
       ,('Succeeded')
       ,('Processing')
    ) AS s ([State])
  LEFT JOIN 
    dbo.Job AS j
      ON
      s.[State] = j.[State]
GROUP BY
  s.[State];
0
Eric Brandt 10 sep. 2018 a las 16:29

Puede agregar una agrupación adicional alrededor de su consulta original:

SELECT State, SUM(Total) FROM ( SELECT State, COUNT(State) AS Total FROM dbo.Job GROUP BY State UNION SELECT 'Processing' AS State, 0 AS Total) GROUP BY State

Si hay entradas de 'Procesamiento' en su tabla dbo.Job, se agregarán al 0 desde la Unión.

La otra opción es como Matt D sugirió: crear una tabla de referencia con todos los estados posibles y luego IZQUIERDA EXTERIOR ÚNETE a la tabla dbo.Job.

SELECT s.State, COUNT(j.State) AS Total
FROM dbo.All_States s
LEFT OUTER JOIN dbo.Job j
ON s.State = j.State
GROUP BY s.State
0
stompydragons 10 sep. 2018 a las 14:58

Puede usar LEFT JOIN para traducir la tabla que contiene todos los estados posibles:

SELECT s.State, COUNT(j.State) AS Total
FROM StateTable s
LEFT JOIN dbo.Job j
  ON s.state = j.state
GROUP BY s.State
1
Lukasz Szozda 10 sep. 2018 a las 14:52

Haga una tabla con todos los estados y únala o codifique una lista de estados en su secuencia de comandos (pero esta es probablemente una mala forma de hacerlo).

0
mttyd 10 sep. 2018 a las 14:54

Puede usar rollup:

SELECT coalesce(state,'Processing') as State, sum(Total) as Total
  FROM dbo.Job
 GROUP BY rollup(State);

Rextester Demo

0
Barbaros Özhan 10 sep. 2018 a las 15:08