所以我有一些数据库实体描述了所述项目中的项目和用户:
然后我编写了一个查询以获取项目集合,以及一个额外的字段来获取项目中的用户数量:
select x.RefProject, x.ProjectName, x.DateCreated, x.PlannedDueDate,
(select count(RefUser) from ProjectUsers where RefProject = x.RefProject) as ProjectUserCount
from Projects x
left outer join ProjectUsers a on x.RefProject = a.RefProject
where a.RefUser = 1
我的问题是 - 有更好的方法来计算用户数吗?我觉得像CTE表或功能将是更正确的"这样做的方法。
答案 0 :(得分:2)
首先,您的where
子句将外连接转换为内连接。所以你可能也是明确的。然后使用窗口函数:
select p.RefProject, p.ProjectName, p.DateCreated, p.PlannedDueDate,
count(*) over (partition by p.RefProject) as ProjectUserCount
from Projects p join
ProjectUsers pu
on p.RefProject = pu.RefProject
where pu.RefUser = 1;
编辑:
我发现过滤器可能会限制实际数量。更准确的表示使用子查询:
select p.*
from (select p.RefProject, p.ProjectName, p.DateCreated, p.PlannedDueDate,
count(*) over (partition by p.RefProject) as ProjectUserCount,
pu.RefUser
from Projects p join
ProjectUsers pu
on p.RefProject = pu.RefProject
) p
where RefUser = 1;
答案 1 :(得分:2)
替代方法是编写一个按RefProject
分组的子查询,完成总和,然后加入你的表。
SELECT x.RefProject, x.ProjectName, x.DateCreated, x.PlannedDueDate, T.Cnt
FROM Projects AS x
LEFT JOIN ( SELECT RefProject, COUNT(RefUser) AS Cnt
FROM ProjectUser
GROUP BY RefProject) AS T
ON T.RefProject = x.RefProject
LEFT JOIN ProjectUsers AS a
ON x.RefProject = a.RefProject
WHERE a.RefUser = 1;
使用标量函数或多语句表值函数会降低性能,这个和你的查询都很好,只需很好地索引表,这样就可以了。
或者,如果分组成为问题,您可以创建索引视图并与其连接。这会增加一些写入开销,但会对读取性能产生奇迹。
CREATE VIEW RefProjectCountView
WITH SCHEMABINDING
AS
SELECT RefProject, COUNT_BIG(RefUser) AS Cnt
FROM ProjectUser
GROUP BY RefProject;
GO
CREATE UNIQUE CLUSTERED INDEX PK_RefProjectCountView
ON RefProjectCountView (RefProject);
GO
SELECT x.RefProject, x.ProjectName, x.DateCreated, x.PlannedDueDate, T.Cnt
FROM Projects AS x
LEFT JOIN RefProjectCountView AS T WITH(NOEXPAND)
ON T.RefProject = x.RefProject
LEFT JOIN ProjectUsers AS a
ON x.RefProject = a.RefProject
WHERE a.RefUser = 1;
SQL Server需要 WITH(NOEXPAND)
提示来查询视图索引,而不是扩展完整的select语句。