避免编写多个union语句

时间:2014-12-10 00:02:18

标签: sql tsql union

我必须获取一个记录列表,这些记录显示每个呼叫类型过去8周按周收到的呼叫总数。有没有更好的方法在MSSQL中编写它?我应该查看哪些术语或参考文献?

我想避免在WHERE子句中使用具有不同LIKES的多个联合。

SELECT 
    'Agent did not speak to Business Owner' AS QCDescription, 
    CONVERT(float ,SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd   THEN 1 ELSE 0 END)) [LastWeek]
FROM 
    dbo.[Call] c JOIN
    dbo.[User] u on c.UserID = u.UserID
WHERE 
    c.IsPassedQC = 0 
    AND (c.QCDate IS NOT NULL AND c.VerifiedDate > '11/4/2013')
    AND (c.CallCenterID = 0 OR c.CallCenterID = u.CallCenterID)
    AND  c.QCReason LIKE '%Agent did not speak to Business Owner%' --dbo.QCResason.Description 
UNION 
    SELECT 
    'Agent explained Radius' AS QCDescription, 
    CONVERT(float ,SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd   THEN 1 ELSE 0 END)) [LastWeek]
FROM 
    dbo.[Call] c 
    JOIN dbo.[User] u on c.UserID = u.UserID 
WHERE 
    c.IsPassedQC = 0 
    AND (c.QCDate IS NOT NULL AND c.VerifiedDate > '11/4/2013')
    AND (c.CallCenterID = 0 OR c.CallCenterID = u.CallCenterID)
    AND  c.QCReason LIKE '%Agent explained Radius%' --dbo.QCReason.Description

取值

dbo.Call
CallID bigint
VerifiedDate datetime,
QCDate datetime
QCResason varchar(500),
QCUserID

dbo.QCReason
QCReasonID int,
Reason varchar(100),
Description(varchar(200)

2 个答案:

答案 0 :(得分:2)

如果您可以处理多个列而不是多个行,那么您可以使用条件聚合:

SELECT SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd AND
                     c.QCReason LIKE '%Agent did not speak to Business Owner%'
                THEN 1 ELSE 0 END) as DidNotSpeaktoBusinessOwner,
       SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd AND
                     c.QCReason LIKE '%Agent explained Radius%'
                THEN 1 ELSE 0 END) as AgentExplainedRadius  
FROM dbo.[Call] c JOIN
     dbo.[User] u
     on c.UserID = u.UserID
WHERE c.IsPassedQC = 0 AND
      (c.QCDate IS NOT NULL AND c.VerifiedDate > '2013-11-04')
      (c.CallCenterID = 0 OR c.CallCenterID = u.CallCenterID)

编辑:

这是一种可以在不同的行上获得结果的方法。请注意,这可能不会像以前的查询一样好:

with patterns as (
      select 'Agent did not speak to Business Owner' as name,
             '%Agent did not speak to Business Owner%' as pattern union all
      select 'Agent explained Radius', '%Agent explained Radius%'
     )
SELECT patterns.name,
       SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd AND
                     c.QCReason LIKE patterns.pattern
                THEN 1 ELSE 0 END)
FROM patterns cross join
     dbo.[Call] c JOIN
     dbo.[User] u
     on c.UserID = u.UserID
WHERE c.IsPassedQC = 0 AND
      (c.QCDate IS NOT NULL AND c.VerifiedDate > '2013-11-04')
      (c.CallCenterID = 0 OR c.CallCenterID = u.CallCenterID)
GROUP BY  patterns.name;

答案 1 :(得分:0)

我把它拼凑在一起并且无法测试它(语法或可行性),但这样的事情可以起作用:

SELECT
    case
      when c.QCReason LIKE '%Agent explained Radius%' then 'Agent explained Radius'
      when c.QCReason LIKE '%Agent did not speak to Business Owner%' then 'Agent did not speak to Business Owner'
      else 'xxx'
    end  QCDescription,
    CONVERT(float ,SUM(CASE WHEN c.VerifiedDate BETWEEN @LastWeekStart AND @LastWeekEnd   THEN 1 ELSE 0 END)) [LastWeek]
FROM 
    dbo.[Call] c JOIN
    dbo.[User] u on c.UserID = u.UserID
WHERE 
    c.IsPassedQC = 0 
    AND (c.QCDate IS NOT NULL AND c.VerifiedDate > '11/4/2013')
    AND (c.CallCenterID = 0 OR c.CallCenterID = u.CallCenterID)
GROUP BY
    case
      when c.QCReason LIKE '%Agent explained Radius%' then 'Agent explained Radius'
      when c.QCReason LIKE '%Agent did not speak to Business Owner%' then 'Agent did not speak to Business Owner'
      else 'xxx'
    end
HAVING
    case
      when c.QCReason LIKE '%Agent explained Radius%' then 'Agent explained Radius'
      when c.QCReason LIKE '%Agent did not speak to Business Owner%' then 'Agent did not speak to Business Owner'
      else 'xxx'
    end <> 'xxx'

having条款让我很紧张。如果失败,您需要一个花哨的where子句来过滤c.QCReason。另一个问题,如果没有这样的行,你就不会得到0,你只是赢得了那个值的行。