Comment dois-je faire un Upsert Dans la Table?
-
09-06-2019 - |
Question
J'ai une vue qui a une liste de tâches, avec des données, comme qui ils sont affectés et la scène, ils sont.J'ai besoin d'écrire une procédure stockée qui retourne le nombre d'emplois chaque personne a à chaque étape.
Pour l'instant j'ai ceci (simplifié):
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
Le problème c'est que les lignes qui ne combinent pas.Donc, si un membre du personnel a des emplois dans le stage1 et stage2 il y a deux lignes dans @ResultTable.Ce que je voudrais vraiment faire est de mettre à jour la ligne si celle-ci existe pour le membre du personnel et l'insertion d'une nouvelle ligne si l'un n'existe pas.
Personne ne sait comment faire, ou peut proposer une approche différente?Je voudrais vraiment éviter d'utiliser les curseurs pour itérer sur la liste des utilisateurs (mais c'est mon tomber en arrière en option).
Je suis à l'aide de SQL Server 2005.
Edit:@Lee: Malheureusement, le InStage1 = 1, est une simplification.Il est vraiment plus comme le lieu de DateStarted n'EST PAS NULL et DateFinished EST NULL.
Edit:@BCS: J'aime l'idée de faire une insertion de l'ensemble du personnel en premier donc j'ai juste à faire une mise à jour à chaque fois.Mais j'ai du mal à obtenir ces mise à JOUR des énoncés corrects.
La solution
Autant que je me souvienne il y a une sorte de "Doublons" (nom peut être erroné) de la syntaxe qui permet de mettre à jour si une ligne existe (MySQL)
Alternativement, une certaine forme 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)
Autres conseils
En fait, je pense que vous êtes en rend d'autant plus difficile qu'elle ne l'est.Ne pas ce code fonctionne pour ce que vous essayez de faire?
SELECT StaffName, SUM(InStage1) AS 'JobsAtStage1', SUM(InStage2) AS 'JobsAtStage2'
FROM ViewJob
GROUP BY StaffName
Vous pouvez simplement vérifier l'existence et l'utilisation de la commande appropriée.Je crois que ce n'est vraiment utiliser un curseur derrière les scènes, mais c'est le meilleur que vous obtiendrez probablement:
IF (EXISTS (SELECT * FROM MyTable WHERE StaffName = @StaffName))
begin
UPDATE MyTable SET ... WHERE StaffName = @StaffName
end
else
begin
INSERT MyTable ...
end
SQL2008 a une nouvelle FUSION de la capacité de ce qui est cool, mais ce n'est pas en 2005.
Pour obtenir un véritable "upsert" type de requête, vous devez utiliser un si il existe...type de chose, et ce, malheureusement, signifie à l'aide d'un curseur.
Toutefois, vous pouvez exécuter deux requêtes, l'une pour faire vos mises à jour où il y a une ligne existante, puis, ensuite, installez-en un nouveau.Je pense de cet ensemble basée sur la méthode à privilégier, sauf si vous avez affaire exclusivement avec de petits nombres de lignes.
La requête suivante sur votre tableau de résultat devrait combiner les lignes de nouveau.C'est en supposant que InStage1 et InStage2 ne sont jamais les deux '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
J'ai réussi à le faire fonctionner avec une variation du BCS de la réponse.Il ne serait pas me laisser utiliser une variable de table, donc j'ai dû faire une table temporaire.
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