2017-07-07 57 views
1

我已经研究演示如何添加条件使用CASE语句计数语句,但我找不到怎么做,我需要一个例子很多问题#1。假设我有以下表格:计数行基于存在的条件

CREATE TABLE [Project](
    [ProjectId] [int] NOT NULL, 
    [ProjectName] [nvarchar](100) NOT NULL 
) 
GO 

CREATE TABLE [ProjectTask](
    [ProjectTaskId] [int] NOT NULL, 
    [ProjectId] [int] NOT NULL, 
    [TaskName] [nvarchar](100) NOT NULL 
) 
GO 

CREATE TABLE [ProjectTaskOwner](
    [ProjectTaskId] [int] NOT NULL, 
    [UserId] [int] NOT NULL 
) 
GO 

CREATE TABLE [ProjectTaskEntity](
    [ProjectTaskId] [int] NOT NULL, 
    [EntityId] [int] NOT NULL, 
    [AssignedUserId] [int] 
) 
GO 

INSERT Project (ProjectId, ProjectName) VALUES (1, 'Test Project') 
INSERT ProjectTask (ProjectTaskId, ProjectId, TaskName) VALUES(1, 1, 'Task1') 
INSERT ProjectTask (ProjectTaskId, ProjectId, TaskName) VALUES(2, 1, 'Task2') 
INSERT ProjectTaskOwner (ProjectTaskId, UserId) VALUES (1, 1) 
INSERT ProjectTaskOwner (ProjectTaskId, UserId) VALUES (1, 2) 
INSERT ProjectTaskOwner (ProjectTaskId, UserId) VALUES (1, 3) 
INSERT ProjectTaskEntity (ProjectTaskId, EntityId, AssignedUserId) VALUES (1, 1, 1) 
INSERT ProjectTaskEntity (ProjectTaskId, EntityId, AssignedUserId) VALUES (1, 2, 2) 
INSERT ProjectTaskEntity (ProjectTaskId, EntityId, AssignedUserId) VALUES (1, 3, 3) 
INSERT ProjectTaskEntity (ProjectTaskId, EntityId, AssignedUserId) VALUES (1, 4, 256) 

我想要做的就是让每个项目任务分配给我,并分配给其他任务所有者的实体的数量。因此,对于上面的测试数据,鉴于1的用户ID和1项目ID我想到:

| TaskId | AssignedToMe | AssignedToOthers | 
| 1 |  1  |  2   | 
| 2 |  0  |  0   | 

所以这是我到目前为止有:

DECLARE @userId INT = 1 
SELECT 
    pt.ProjectId, 
    pt.ProjectTaskId, 
    COUNT(CASE WHEN pte.AssignedUserId = @userId THEN 1 ELSE NULL END) AS AssignedTo 
FROM ProjectTask pt 
INNER JOIN Project p 
    ON p.ProjectId = pt.ProjectId 
LEFT JOIN ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId 
WHERE p.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId 

分配给我的是容易。问题是我不知道如何去做别人,因为别人不只是我不是。任何人都不在此任务的ProjectTaskOwner表中。任何人有任何想法如何实现这一目标?

回答

0

这里是解决我的问题的实际查询。有几个职位,帮我找到这个所以感谢大家对你的答案:

DECLARE @userId INT = 1 
SELECT 
    pt.ProjectId, 
    pt.ProjectTaskId, 
    COUNT(CASE WHEN pte.AssignedUserId = @userId THEN 1 ELSE NULL END) AS AssignedTo, 
    COUNT(CASE WHEN eao.OtherUser IS NULL THEN NULL ELSE 1 END) AS AssignedToOther 
FROM ProjectTask pt 
LEFT JOIN ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId 
LEFT JOIN (
    SELECT sPto.ProjectTaskId, sPto.UserId as OtherUser 
    FROM ProjectTaskOwner sPto 
    WHERE sPto.UserId <> @userId 
) eao 
    ON pt.ProjectTaskId = eao.ProjectTaskId AND pte.AssignedUserId = eao.OtherUser 
WHERE pt.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId 
0

这就像做相反

DECLARE @userId INT = 1 
SELECT 
    pt.ProjectId, 
    pt.ProjectTaskId, 
    COUNT(CASE WHEN pte.AssignedUserId = @userId THEN 1 ELSE NULL END) AS AssignedToMe, 
    COUNT(CASE WHEN pte.AssignedUserId = @userId THEN null ELSE 0 END) AS AssignedToOthers 

FROM ProjectTask pt 
INNER JOIN Project p 
    ON p.ProjectId = pt.ProjectId 
LEFT JOIN ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId 
WHERE p.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId 
+0

感谢您的评论,但你忽略了一点关于它没有比我其他的只是用户,但其他用户也分配给该作为业主的任务。 –

1

我不明白为什么你需要项目表这么简单。我会写这样的:

SELECT pt.ProjectId, pt.ProjectTaskId, 
     SUM(CASE WHEN pte.AssignedUserId = @userId THEN 1 ELSE 0 END) AS AssignedToMe, 
     SUM(CASE WHEN pto.UserId IS NULL THEN 1 ELSE 0 END) AS AssignedToOthers 
FROM ProjectTask pt LEFT JOIN 
    ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId LEFT JOIN 
    ProjectTaskOwner pto 
    ON pto.ProjectTaskId = pt.ProjectTaskId AND 
     pto.UserId = pte.AssignedUserId 
WHERE pt.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId; 

SUM()取代COUNT()。作为一个优先事项,在这种情况下,我更喜欢SUM()

+0

您查询返回'AssignedToOthers' = 1任务2中看到这个[**小提琴**](http://www.sqlfiddle.com/#!6/58f1e4/11)。 –

+0

@RagingBull。 。 。 OP在两个不同的段落中解释了条件 - 解释有些不同。我在最后一段中解释了答案。 –

+0

@GordonLinoff ...很抱歉的额外join..my实际情况更为复杂,我忘了删除加入。您的解决方案很近,但对Task2生成AssignedToOthers = 1,对于Task1生成AssignedToOthers = 1。答案是 任务1 - AssignedToMe = 1分配给其他人= 2 任务2 - AssignedToMe = 0分配给其他人= 0 –

0

使用SUM代替COUNT

DECLARE @userId INT = 1 
SELECT pt.ProjectTaskId, 
    ISNULL(SUM(CASE WHEN pte.AssignedUserId = @userId THEN 1 END),0) AS AssignedToMe, 
    ISNULL(SUM(CASE WHEN pte.AssignedUserId <> @userId THEN 1 END),0) AS AssignedToOthers 
FROM ProjectTask pt 
INNER JOIN Project p ON p.ProjectId = pt.ProjectId 
LEFT JOIN ProjectTaskEntity pte ON pte.ProjectTaskId = pt.ProjectTaskId 
WHERE p.ProjectId = 1 
GROUP BY pt.ProjectTaskId 

与您所提供的数据,这将导致:

ProjectTaskId AssignedToMe AssignedToOthers 
1    1    3 
2    0    0 

参见导致SQL Fiddle

+0

感谢您的评论,但您错过了关于它的观点,不仅仅是我以外的用户,而是其他用户也作为所有者分配给这项任务。 –

0

我认为这解决了这个问题。 你会看别人的不是你,任何人都不能在ProjectTaskOwner表完成这个任务。

DECLARE @userId INT = 1 
SELECT 
    pt.ProjectId, 
    pt.ProjectTaskId, 
    COUNT(CASE WHEN pte.AssignedUserId = @userId THEN 1 ELSE NULL END) AS AssignedTo, 
    COUNT(CASE WHEN pte.AssignedUserId != @userId AND pte.AssignedUserId != pto.UserId THEN 1 ELSE NULL END) AS AssignedTo 
FROM ProjectTask pt 
INNER JOIN Project p 
    ON p.ProjectId = pt.ProjectId 
LEFT JOIN ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId 
LEFT JOIN ProjectTaskOwner pto 
    on pto.ProjectTaskId = pt.ProjectTaskId 
WHERE p.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId 
+0

由于额外的连接,人为地夸大了数字。例如,您的查询将3分配给我,将7分配给其他人。结果应该是1分配给我,2分配给其他人。 –

0
DECLARE @userId INT = 1 
SELECT 
    pt.ProjectId, 
    pt.ProjectTaskId, 
    ISNULL(SUM(CASE WHEN pte.AssignedUserId = @userId THEN 1 END),0) AS AssignedToMe, 
    ISNULL(SUM(CASE WHEN pte.AssignedUserId <> @userId THEN 1 END),0) AS AssignedToOthers 
FROM ProjectTask pt 
INNER JOIN Project p 
    ON p.ProjectId = pt.ProjectId 
LEFT JOIN ProjectTaskOwner pto 
    ON pto.ProjectTaskId = pt.ProjectTaskId 
LEFT JOIN ProjectTaskEntity pte 
    ON pte.ProjectTaskId = pt.ProjectTaskId and 
    pte.AssignedUserId = pto.UserId 
WHERE p.ProjectId = 1 
GROUP BY pt.ProjectId, pt.ProjectTaskId 

http://www.sqlfiddle.com/#!6/58f1e4/28

+0

是的,这是答案。谢谢! –