如何获得列的总和,其中另一列具有Count = 1

时间:2013-05-24 14:52:26

标签: sql select group-by distinct

示例数据:

+===========================================================================+
|NoBoxes | Carrier | ProcessDateTime | Errored | Voided | TrackingNumber    |
+===========================================================================+
|  2     |  UPS    | 5/22/2013 8:14  |    0    |    0   | 1Z1234567891234567|
+---------------------------------------------------------------------------+
|        |  UPS    |                 |    0    |    1   | 1Z1234567891234567|
+---------------------------------------------------------------------------+    
|  5     |  UPS    | 5/22/2013 8:22  |    1    |    0   |                   |
+---------------------------------------------------------------------------+
|  7     |  UPS    | 5/22/2013 8:14  |    0    |    0   | 1Z9876543210987654|
+---------------------------------------------------------------------------+
|  1     |  UPS    | 5/22/2013 8:22  |    0    |    0   | 1Z1472583691472583|
+---------------------------------------------------------------------------+
|  1     |  FedEx  | 5/22/2013 8:14  |    0    |    0   | xxxxxxxxxxxxxxxx  |
+---------------------------------------------------------------------------+
|  8     |  FedEx  | 5/22/2013 8:22  |    0    |    0   | yyyyyyyyyyyyyyyy  |
+---------------------------------------------------------------------------+
|  3     |  USPS   | 5/22/2013 8:14  |    0    |    0   | zzzzzzzzzzzzzzzz  |
+---------------------------------------------------------------------------+
|  4     |  USPS   | 5/22/2013 8:22  |    0    |    0   | aaaaaaaaaaaaaaaa  |
+---------------------------------------------------------------------------+
|  7     |  UPS    | 5/22/2013 8:14  |    0    |    0   | 1Z9638527411012396|
+---------------------------------------------------------------------------+
|  9     |  UPS    | 5/22/2013 8:22  |    0    |    0   | 1Z4561591981655445|
+---------------------------------------------------------------------------+

现在使用这样的表格,如何得到NoBoxes其中Carrier = UPS,ProcessDateTime =今天,Errored = 0和{{{{}}的总和1}}计数= 1?

重复的跟踪号代表无效的货件。 我不想将TrackingNumber货物总计为那些没有发货的货物。

我尝试了大约10种不同的陈述,似乎没有任何东西可以让我得到我需要的地方。

相信 的问题是,无效行不包含Errored

所以当我使用类似的东西时:

ProcessDateTime

由于查询不包含null SELECT Sum(NoBoxes) FROM Info WHERE (Carrier='UPS') AND (ProcessDateTime>{ts '2013-05-23 00:00:00'} And ProcessDateTime<{ts '2013-05-24 00:00:00'}) AND (Errored=0) GROUP BY TrackingNumber HAVING (Count(*)=1) 的任何行

,它仍会返回已失效的TrackingNumber

然后我尝试了:

ProcessDateTime

但是这仍然不能完成它只返回一切的工作。

还尝试了SELECT Sum(NoBoxes), ProcessDateTime FROM Info WHERE ((Carrier='UPS') AND (Errored=0)) OR ((Carrier='UPS') AND (ProcessDateTime Is Null) AND (Errored=0)) GROUP BY ProcessDateTime, TrackingNumber HAVING (Count(*)=1) ,但似乎没有做任何事情。

我无法弄清楚如何摆脱所有重复的跟踪号码,然后返回标准内HAVING (Count(TrackingNumber)=1)UPS的所有ProcessDateTime的总和。因为似乎摆脱重复的唯一方法是根本不使用ProcessDateTime,但是我无法告诉ProcessDateTime是什么,我需要知道才能过滤具体日期。

我有点明白我可能要做的事情如下:

(Select TrackingNumber 
 From Info 
 Where Carrier = 'UPS' And Errored = 0
 Group By TrackingNumber HAVING Count(*) = 1) As A

然后按照以下方式做点什么:

Select  Sum(NoBoxes) As Total
From Info
Join A On Info.TrackingNumber = A.TrackingNumber
Where Info.ProcessDateTime>{ts '2013-05-23 00:00:00'} And 
      Info.ProcessDateTime<{ts '2013-05-24 00:00:00'}

但我对此并不了解,以便在这样的查询中获得正确的顺序和语法。

根据提供的表格,我希望返回一行,其中一列的值为24

4 个答案:

答案 0 :(得分:1)

Select Sum( NoBoxes )
From Info As I
Where Carrier = 'UPS'
    And ProcessDateTime >= '2013-05-22 00:00:00'
    And ProcessDateTime < '2013-05-23 00:00:00'
    And Errored = 0
    And Voided = 0
    And Not Exists  (
                    Select 1
                    From Info As I1
                    Where I1.TrackingNumber = I.TrackingNumber
                        And Voided <> 0                         
                    )

我注意到的一项是您的示例查询中的日期范围与您提供的示例数据不重叠。下面是SQL Fiddle版本的链接。您没有指定数据库和版本,因此我使用了SQL Server,但上述解决方案应该适用于几乎所有数据库产品。

SQL Fiddle version

答案 1 :(得分:0)

我认为您只想在第一个查询中添加ProcessDateTime = NULL支票:

SELECT Sum(NoBoxes)
FROM Info
WHERE (Carrier='UPS') AND
      ((ProcessDateTime>{ts '2013-05-23 00:00:00'} And ProcessDateTime<{ts '2013-05-24 00:00:00'}) or
       ProcessDateTime is NULL
      ) AND
      (IsError=0)
GROUP BY TrackingNumber
HAVING (Count(*)=1)

如果你想要总和,那么把它作为一个子查询,并从中加总值。

答案 2 :(得分:0)

这就是一切。第一部分是我创建的测试。第二部分是你需要的

DECLARE @Info TABLE
(
    NoBoxes int,
    Carrier varchar(50),
    ProcessDateTime DateTime,
    Errored int,
    Voided int,
    TrackingNumber varchar(100)
)

Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 2, 'UPS', '2013-05-22 8:14', 0, 0, '1Z1234567891234567')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( NULL, 'UPS', NULL, 0, 1, '1Z1234567891234567')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 5, 'UPS', '2013-05-22 8:22', 1, 0, NULL)
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 7, 'UPS', '2013-05-22 8:14', 0, 0, '1Z9876543210987654')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 1, 'UPS', '2013-05-22 8:22', 0, 0, '1Z1472583691472583')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 1, 'FedEx', '2013-05-22 8:14', 0, 0, 'xxxxxxxxxxxxxxxx')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 8, 'FedEx', '2013-05-22 8:22', 0, 0, 'yyyyyyyyyyyyyyyy')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 3, 'USPS', '2013-05-22 8:14', 0, 0, 'zzzzzzzzzzzzzzzz')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 4, 'USPS', '2013-05-22 8:22', 0, 0, 'aaaaaaaaaaaaaaaa')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 7, 'UPS', '2013-05-22 8:14', 0, 0, '1Z9638527411012396')
Insert into @Info (NoBoxes, Carrier, ProcessDateTime, Errored, Voided, TrackingNumber) Values ( 9, 'UPS', '2013-05-22 8:22', 0, 0, '1Z4561591981655445')




;

我肯定会使用CTE

WITH FIRSTCTE (TrackingNumber)
AS
(
    Select TrackingNumber 
    From @Info 
    Where Carrier = 'UPS' And Errored = 0
    Group By TrackingNumber
)
select *
FROM FIRSTCTE as C
    INNER JOIN @Info as I
        ON I.TrackingNumber = C.TrackingNumber
WHERE DATEADD(D, 0, DATEDIFF(D, 0, I.ProcessDateTime)) = '2013-05-22'

答案 3 :(得分:0)

在阅读了我自己的问题后,我意识到如何使用完全相同的子查询来实现这一点,尽管我应该这样做,这完全符合我的希望。

Select  Sum(NoBoxes) As Total

From Info

Join 
    (Select TrackingNumber 
     From Info 
     Where Carrier = 'UPS' And Errored = 0
     Group By TrackingNumber HAVING Count(*) = 1) As A

On Info.TrackingNumber = A.TrackingNumber

Where Info.ProcessDateTime>{ts '2013-05-22 00:00:00'} And 
      Info.ProcessDateTime<{ts '2013-05-23 00:00:00'}