在sql中计算不带union的表中的多个值

时间:2017-09-25 17:08:07

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

我有与各种WIPReason关联的validationErrors,我想根据不同的WIPReason计算,我使用Union All并且它可以工作但查询非常大,多个wip原因超过10.请找到下面的查询

SELECT       
    COUNT(tlv.TransactionLineId) AS TotalErrors,
    COUNT(tl.Id) AS TotalLines,
    COUNT(tlv.Reason) AS NoWorkRecords,
    0 AS ValidationErrors
FROM
    dbo.TimesheetCellTransactionLine tctl
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id
WHERE 
    tl.CurrentStatus = 1
    AND w.Id = 4 -- NoWorkRecords
GROUP BY 
    tlv.TransactionLineId, tl.Id

UNION ALL

SELECT 
    COUNT(tlv.TransactionLineId) AS TotalErrors,
    COUNT(tl.Id) AS TotalLines,
    0 AS NoWorkRecords,
    COUNT(tlv.Reason) AS ValidationErrors
FROM
    dbo.TimesheetCellTransactionLine tctl
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id
WHERE 
    tl.CurrentStatus = 1
    AND w.Id = 1 -- validationErrors
GROUP BY 
    tlv.TransactionLineId, tl.Id

对于w.Id = 1到10

,还有其他优雅的方法吗?
  

AND w.Id = 1 - validationErrors

更新: 我希望结果作为列10计数列,因为我在另一个大选择中使用它。

2 个答案:

答案 0 :(得分:1)

SELECT COUNT(tlv.TransactionLineId) OVER (partition by (w.Id)  order by w.Id) AS TotalErrors,
       COUNT(tl.Id) OVER (partition by (w.Id)  order by w.Id) AS TotalLines,
       0 AS NoWorkRecords,
       COUNT(tlv.Reason) OVER (partition by (w.Id)  order by w.Id)  AS ValidationErrors
FROM dbo.TimesheetCellTransactionLine tctl
     INNER JOIN dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
     INNER JOIN dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
     INNER JOIN dbo.WIPReason w ON tlv.Reason = w.Id
WHERE tl.CurrentStatus = 1
      AND w.Id between 1 and 10 -- validationErrors
GROUP BY tlv.TransactionLineId,
         tl.Id,tlv.Reason

答案 1 :(得分:1)

您可以在case内使用count语句,如下所示:

SELECT       
    COUNT(tlv.TransactionLineId) AS TotalErrors,
    COUNT(tl.Id) AS TotalLines,
    COUNT(case when w.Id = 4 then tlv.Reason else null end) AS NoWorkRecords,
    COUNT(case when w.Id = 1 then tlv.Reason else null end) AS ValidationErrors,
    ... Repeat for remaining w.Id's ...
FROM
    dbo.TimesheetCellTransactionLine tctl
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id
WHERE 
    tl.CurrentStatus = 1
GROUP BY 
    tlv.TransactionLineId, tl.Id

注意 由于您使用的是inner join on tl.Id = tlv.TransactionLineId

  1. TotalErrors/TotalLines总是一样的
  2. 不需要tl.Idtlv.TransactionLineId分组