我有一个视图,其中包含一个作业列表,其中包含分配给他们的人员以及他们所处的阶段。我需要编写一个存储过程来返回每个人在每个阶段有多少个工作
到目前为止,我有这个(简化):
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
问题在于行没有合并。因此,如果一名工作人员在stage1和stage2中有作业,则@ResultTable中有两行。我真正想做的是更新行(如果工作人员存在一行)并插入一个新行(如果不存在)。
有谁知道如何做到这一点,还是可以提出不同的方法? 我真的想避免使用游标迭代用户列表(但这是我的后退选项)。
我正在使用SQL Server 2005。
编辑:@Lee:不幸的是,InStage1 = 1是一种简化。它更像是WHERE DateStarted IS NOT NULL而DateFinished IS NULL。
编辑:@BCS:我喜欢先插入所有员工的想法,所以我每次都要做更新。但是我很难让这些UPDATE语句正确。
答案 0 :(得分:3)
实际上,我认为你做得比现在困难得多。这段代码不会适用于你想要做的事情吗?
SELECT StaffName, SUM(InStage1) AS 'JobsAtStage1', SUM(InStage2) AS 'JobsAtStage2'
FROM ViewJob
GROUP BY StaffName
答案 1 :(得分:2)
您可以检查是否存在并使用适当的命令。我相信这确实在幕后使用光标,但它是你可能得到的最好的:
IF (EXISTS (SELECT * FROM MyTable WHERE StaffName = @StaffName))
begin
UPDATE MyTable SET ... WHERE StaffName = @StaffName
end
else
begin
INSERT MyTable ...
end
SQL2008有一个新的MERGE功能很酷,但它不是在2005年。
答案 2 :(得分:1)
要获得真正的“upsert”类型的查询,您需要使用if exists ...类型的东西,这不幸意味着使用游标。
但是,您可以运行两个查询,一个用于在存在现有行的情况下进行更新,然后再插入新查询。我认为这种基于集合的方法更可取,除非你只处理少量的行。
答案 3 :(得分:1)
IIRC存在某种“On Duplicate”(名称可能错误)语法,如果存在行(MySQL),则可以更新
或者某种形式:
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)
答案 4 :(得分:0)
结果表上的以下查询应再次合并行。这假设InStage1和InStage2永远都不是'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
答案 5 :(得分:0)
我成功地使用了BCS的各种答案。它不会让我使用表变量,所以我不得不制作临时表。
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