3

我有一个视图,其中包含工作列表,其中包含诸如分配给谁以及他们所处阶段之类的数据。我需要编写一个存储过程来返回每个人在每个阶段有多少工作。

到目前为止,我有这个(简化):

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 语句正确。

4

6 回答 6

3

实际上,我认为你让它变得比现在更难。这段代码对你想要做的事情不起作用吗?

SELECT StaffName, SUM(InStage1) AS 'JobsAtStage1', SUM(InStage2) AS 'JobsAtStage2'
  FROM ViewJob
GROUP BY StaffName
于 2008-08-20T23:58:32.377 回答
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 年。

于 2008-08-20T23:57:20.320 回答
1

要获得真正的“upsert”类型的查询,您需要使用 if exists... 类型的东西,不幸的是,这意味着使用游标。

但是,您可以运行两个查询,一个在存在现有行的地方进行更新,然后插入新的。我认为这种基于集合的方法会更可取,除非您只处理少量行。

于 2008-08-20T23:55:04.710 回答
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)
于 2008-08-21T00:09:16.580 回答
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
于 2008-08-21T00:03:12.850 回答
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
于 2008-08-21T01:40:23.397 回答