Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于存在条件计算行数_Sql_Sql Server_Tsql_Count_Aggregate Functions - Fatal编程技术网

Sql 基于存在条件计算行数

Sql 基于存在条件计算行数,sql,sql-server,tsql,count,aggregate-functions,Sql,Sql Server,Tsql,Count,Aggregate Functions,我研究了许多Stackoverflow问题,这些问题演示了如何使用CASE语句向COUNT语句添加条件,但我找不到一个示例来说明如何执行我需要的操作。假设我有以下表格: CREATE TABLE [Project]( [ProjectId] [int] NOT NULL, [ProjectName] [nvarchar](100) NOT NULL ) GO CREATE TABLE [ProjectTask]( [ProjectTaskId] [int] NOT NU

我研究了许多Stackoverflow问题,这些问题演示了如何使用CASE语句向COUNT语句添加条件,但我找不到一个示例来说明如何执行我需要的操作。假设我有以下表格:

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)
我想做的是为每个项目任务获取分配给我和分配给其他任务所有者的实体数。对于上面的测试数据,假设用户id为1,项目id为1,我希望:

| 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表中的任何人。有人知道如何做到这一点吗?

这就像做相反的事情一样简单

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

我不明白为什么您需要为此项目创建表。我将这样写:

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。在这种情况下,我更喜欢求和。

使用求和而不是计数:


请参见中的结果。

我认为这解决了问题。 对于此任务,您将把其他人计算为非您和不在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

这是解决我问题的实际查询。有几个帖子帮助我找到了这一点,感谢大家的回答:

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

您可以查询任务2的返回AssignedToOthers=1。看这个。@RagingBull。OP在两个不同的段落中解释了这些情况——解释有些不同。我在最后一段修正了解释的答案。@GordonLinoff…对额外的连接感到抱歉..我的实际情况更复杂,我忘了删除该连接。您的解决方案已关闭,但为Task2生成AssignedToOthers=1,而为Task1仅生成1。答案是Task 1-AssignedToMe=1 Assigned To Others=2 Task 2-AssignedToMe=0 Assigned To Others=0由于额外的连接,它人为地增加了数字。例如,您的查询将3个分配给我,7个分配给其他人。结果应该是1分配给我,2分配给其他人。感谢您的评论,但您没有注意到这一点,不仅是我以外的用户,而且是作为所有者分配给此任务的其他用户。感谢您的评论,但您没有注意到这一点,不仅是我以外的用户,而且是分配给此任务的其他用户作为所有者的任务。是的,这是答案。谢谢
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
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
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