Pregunta

Tengo una vista que tiene una lista de trabajos, con datos como a quién están asignados y la etapa en la que se encuentran.Necesito escribir un procedimiento almacenado que devuelva cuántos trabajos tiene cada persona en cada etapa.

Hasta ahora tengo esto (simplificado):

DECLARE @ResultTable table 
(
  StaffName nvarchar(100),
  Stage1Count int,
  Stage2Count int
)

INSERT INTO @ResultTable (StaffName, Stage1Count)
  SELECT StaffName, COUNT(*) FROM ViewJob
  WHERE InStage1 = 1
  GROUP BY StaffName

INSERT INTO @ResultTable (StaffName, Stage2Count)
  SELECT StaffName, COUNT(*) FROM ViewJob
  WHERE InStage2 = 1
  GROUP BY StaffName

El problema con eso es que las filas no se combinan.Entonces, si un miembro del personal tiene trabajos en la etapa 1 y la etapa 2, hay dos filas en @ResultTable.Lo que realmente me gustaría hacer es actualizar la fila si existe una para el miembro del personal e insertar una nueva fila si no existe.

¿Alguien sabe cómo hacer esto o puede sugerir un enfoque diferente?Realmente me gustaría evitar el uso de cursores para iterar en la lista de usuarios (pero esa es mi opción alternativa).

Estoy usando SQL Server 2005.

Editar:@Sotavento: Desafortunadamente, InStage1 = 1 fue una simplificación.En realidad, es más como DONDE DateStarted NO ES NULO y DateFinished ES NULO.

Editar:@BCS: Me gusta la idea de hacer una inserción de todo el personal primero, así solo tengo que hacer una actualización cada vez.Pero estoy luchando por corregir esas declaraciones de ACTUALIZACIÓN.

¿Fue útil?

Solución

IIRC hay algún tipo de sintaxis "Al duplicar" (el nombre puede ser incorrecto) que le permite actualizar si existe una fila (MySQL)

Alternativamente alguna forma de:

INSERT INTO @ResultTable (StaffName, Stage1Count, Stage2Count)
  SELECT StaffName,0,0 FROM ViewJob
  GROUP BY StaffName

UPDATE @ResultTable Stage1Count= (
  SELECT COUNT(*) AS count FROM ViewJob
  WHERE InStage1 = 1
  @ResultTable.StaffName = StaffName)

UPDATE @ResultTable Stage2Count= (
  SELECT COUNT(*) AS count FROM ViewJob
  WHERE InStage2 = 1
  @ResultTable.StaffName = StaffName)

Otros consejos

En realidad, creo que lo estás haciendo mucho más difícil de lo que es.¿No funcionará este código para lo que estás intentando hacer?

SELECT StaffName, SUM(InStage1) AS 'JobsAtStage1', SUM(InStage2) AS 'JobsAtStage2'
  FROM ViewJob
GROUP BY StaffName

Podrías simplemente verificar la existencia y usar el comando apropiado.Creo que esto realmente usa un cursor detrás de escena, pero es lo mejor que probablemente obtendrás:

IF (EXISTS (SELECT * FROM MyTable WHERE StaffName = @StaffName))
begin
    UPDATE MyTable SET ... WHERE StaffName = @StaffName
end
else
begin
    INSERT MyTable ...
end 

SQL2008 tiene una nueva capacidad MERGE que es genial, pero no está en 2005.

Para obtener un tipo de consulta real "upsert", necesita usar un if existe...tipo de cosas, y esto desafortunadamente significa usar un cursor.

Sin embargo, puede ejecutar dos consultas, una para realizar las actualizaciones donde hay una fila existente y luego insertar la nueva.Creo que este enfoque basado en conjuntos sería preferible a menos que se trate exclusivamente de un pequeño número de filas.

La siguiente consulta en su tabla de resultados debería combinar las filas nuevamente.Esto supone que InStage1 e InStage2 nunca son ambos '1'.

select distinct(rt1.StaffName), rt2.Stage1Count, rt3.Stage2Count
from @ResultTable rt1
left join @ResultTable rt2 on rt1.StaffName=rt2.StaffName and rt2.Stage1Count is not null
left join @ResultTable rt3 on rt1.StaffName=rt2.StaffName and rt3.Stage2Count is not null

Logré hacerlo funcionar con una variación de la respuesta de BCS.Sin embargo, no me dejaba usar una variable de tabla, así que tuve que crear una tabla temporal.

CREATE TABLE #ResultTable
(
  StaffName nvarchar(100),
  Stage1Count int,
  Stage2Count int
)

INSERT INTO #ResultTable (StaffName)
  SELECT StaffName FROM ViewJob
  GROUP BY StaffName

UPDATE #ResultTable SET 
  Stage1Count= (
    SELECT COUNT(*) FROM ViewJob V
    WHERE InStage1 = 1 AND 
        V.StaffName = @ResultTable.StaffName COLLATE Latin1_General_CI_AS
    GROUP BY V.StaffName),
  Stage2Count= (
    SELECT COUNT(*) FROM ViewJob V
    WHERE InStage2 = 1 AND 
        V.StaffName = @ResultTable.StaffName COLLATE Latin1_General_CI_AS
    GROUP BY V.StaffName)

SELECT StaffName, Stage1Count, Stage2Count FROM #ResultTable

DROP TABLE #ResultTable
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top