T-SQL 运行 针对子查询的多个查询

T-SQL Run multiple queries against a subquery

我有一个针对用户及其请求的简单数据模型:

User
- id,
- name

Request
- id,
- createdAt,
- completedAt,
- status
- userId (FK to user)

我正在尝试 运行 一个为每个用户收集一些统计信息的查询。问题是我必须 运行 相同的子查询来获取用户对每个参数的请求 I select。相反,我想 运行 它一次,然后计算一些统计数据。

select
 u.id as UserId,
 (select count(*) 
  from Requests r 
  where userId = u.id 
      and timestamp > @dateFrom) as Total,
 (select count(*) 
  from Requests r 
  where userId = u.id 
      and timestamp > @dateFrom
      and status = N'Completed') as Completed,
 (select status
  from Requests r 
  where userId = u.id 
      and timestamp > @dateFrom
      and status != N'Completed') as ActiveStatus,
  (select datediff(second, createdAt, completedAt)
   from Requests r 
   where userId = u.id 
      and timestamp > @dateFrom
      and status == N'Completed') as AvgProcessingTime
from User u

显然,这个查询很慢,我需要优化它。我尝试了加入、申请、排名,但对我来说没有任何效果(因为我无法完成对所有必需统计数据的查询)。

从性能的角度来看,最好的方法是什么?

尝试使用 Left Join 和聚合

这里可能有几个问题,但请告诉我你的进展情况。

select
 u.id as UserId
 ,count(r.UserId) [Total]
 ,sum(iif(r.status = N'Completed',1,0)) [Completed]
 ,sum(iif(r.status <> N'Completed',1,0)) [ActiveStatus]
 ,avg(iif(r.status = N'Completed', datediff(second, createdAt, completedAt),0)) [AvgProcessingTime]
from User u
left join Request R
where timestamp > @datefrom
and r.userId = u.id
group by 
u.id

我不确定这个查询,因为我的机器上没有运行它,但是你可以试一试,如果需要的话做一些相应的更改--

SELECT U.ID AS USERID
,COUNT(R.ID) AS TOTAL
,SUM(CASE 
        WHEN R.[STATUS] = N'COMPLETED'
            THEN 1
        END) AS [COMPLETED]
,CASE 
    WHEN R.[STATUS] <> N'COMPLETED'
        THEN [STATUS]
    END AS [ACTIVE STATUS]
,CASE 
    WHEN R.[STATUS] = N'COMPLETED'
        THEN DATEDIFF(SECOND, CREATEDAT, COMPLETEDAT)
    END AS [AVG PROCESSING TIME]
FROM USERS U
LEFT JOIN REQUESTS R ON U.ID = R.USERID
WHERE TIMESTAMP > @DATEFROM