【问题标题】:T-SQL Run multiple queries against a subqueryT-SQL 针对子查询运行多个查询
【发布时间】:2017-05-22 03:32:09
【问题描述】:

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

User
- id,
- name

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

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

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

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

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

【问题讨论】:

  • 应该可以使用左连接并应用聚合来获取计数

标签: sql sql-server tsql sql-server-2012 sqlperformance


【解决方案1】:

使用左连接和聚合试试这个

这里可能存在一些问题,但请告诉我你的进展情况。

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

【讨论】:

  • 它看起来像back to excel,它适用于我的情况!关于ActiveStatus 的唯一问题是没有任何聚合函数可以应用。你有什么建议吗?截至目前,我刚刚在null 上使用status 完成iif 并申请max
  • 我还用null 替换了所有0,以免影响我的avg 功能
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多