Frage

Ich habe eine Ansicht, die eine Liste von Jobs enthält, mit Daten wie der Person, der sie zugewiesen sind, und der Phase, in der sie sich befinden.Ich muss eine gespeicherte Prozedur schreiben, die zurückgibt, wie viele Jobs jede Person in jeder Phase hat.

Bisher habe ich Folgendes (vereinfacht):

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

Das Problem dabei ist, dass die Zeilen nicht kombiniert werden.Wenn also ein Mitarbeiter Jobs in Stufe 1 und Stufe 2 hat, gibt es in @ResultTable zwei Zeilen.Was ich wirklich gerne tun würde, ist, die Zeile zu aktualisieren, falls eine für den Mitarbeiter vorhanden ist, und eine neue Zeile einzufügen, falls keine vorhanden ist.

Weiß jemand, wie das geht, oder kann er einen anderen Ansatz vorschlagen?Ich würde es wirklich gerne vermeiden, Cursor zum Durchlaufen der Benutzerliste zu verwenden (aber das ist meine Ausweichoption).

Ich verwende SQL Server 2005.

Bearbeiten:@Lee: Leider war InStage1 = 1 eine Vereinfachung.Es ist eigentlich eher so, als ob DateStarted NOT NULL und DateFinished NULL ist.

Bearbeiten:@BCS: Mir gefällt die Idee, zuerst alle Mitarbeiter einzufügen, sodass ich jedes Mal ein Update durchführen muss.Aber ich habe Mühe, diese UPDATE-Anweisungen richtig zu machen.

War es hilfreich?

Lösung

IIRC gibt es eine Art „On Duplicate“-Syntax (der Name ist möglicherweise falsch), mit der Sie aktualisieren können, wenn eine Zeile vorhanden ist (MySQL).

Alternativ eine Form von:

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)

Andere Tipps

Eigentlich denke ich, dass Sie es viel schwieriger machen, als es ist.Funktioniert dieser Code nicht für das, was Sie versuchen?

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

Sie könnten einfach die Existenz prüfen und den entsprechenden Befehl verwenden.Ich glaube, dass hier tatsächlich ein Cursor hinter den Kulissen verwendet wird, aber es ist das Beste, was Sie wahrscheinlich bekommen werden:

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

SQL2008 verfügt über eine neue MERGE-Funktion, die cool ist, aber nicht aus dem Jahr 2005.

Um eine echte Abfrage vom Typ „Upsert“ zu erhalten, müssen Sie ein if exist... verwenden.Art von Sache, und das bedeutet leider die Verwendung eines Cursors.

Sie könnten jedoch zwei Abfragen ausführen, eine, um Ihre Aktualisierungen dort durchzuführen, wo eine vorhandene Zeile vorhanden ist, und anschließend die neue einzufügen.Ich denke, dieser satzbasierte Ansatz wäre vorzuziehen, es sei denn, Sie haben es ausschließlich mit einer kleinen Anzahl von Zeilen zu tun.

Die folgende Abfrage Ihrer Ergebnistabelle sollte die Zeilen erneut kombinieren.Dies setzt voraus, dass InStage1 und InStage2 niemals beide „1“ sind.

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

Ich habe es geschafft, es mit einer Variation der BCS-Antwort zum Laufen zu bringen.Da ich jedoch keine Tabellenvariable verwenden konnte, musste ich eine temporäre Tabelle erstellen.

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top