使用SQL Server Sum解决的正确方法

时间:2015-04-14 09:59:22

标签: sql-server

我正在解决一个问题,因为他知道一个号码是否可用。

例如,我有一个存储交易的表,如果交易是传出的,我们将数量存储为负数,如果它存在,则我们将其存储为正数量。

在开始时我认为,如果数量大于零,则SUM足以找到可用但是它不正确,因为根据第二个示例数据,您可以看到'Bike-Serial_001'在然后在后期开始它可用。

如何编写SQL查询和SUM函数来解决此问题?

ID                                          Number              Quantity            syscreated
F7F405B4-CE7E-431B-BAC1-3AC78F436D37    Bike-Serial_001             -1          25-02-2015 12:05:19
279ABB0A-195E-48CB-8443-E5F8E1FCBA38    Bike-Serial_001             1           25-02-2015 12:05:56
25A56A3F-A225-4BBB-B458-9D2CCE3F130D    Bike-Serial_001             1           25-02-2015 12:06:08
EC0C0A4E-651D-4CCD-AFEF-547F973B3243    Bike-Serial_001             -1          25-02-2015 12:07:37
9034E016-19C0-4F3A-A4C6-B84F29D05912    Bike-Serial_001             1           25-02-2015 12:08:14

Another Example in which simple SUM will not be appropriate.

ID                                          Number              Quantity            syscreated
F7F405B4-CE7E-431B-BAC1-3AC78F436D37    Bike-Serial_001             -1          25-02-2015 12:05:19
279ABB0A-195E-48CB-8443-E5F8E1FCBA38    Bike-Serial_001             1           25-02-2015 12:05:56

1 个答案:

答案 0 :(得分:2)

select Number, 
       case when sum(quantity) >= 0 then 1 else 0 end
  from Table
group by Number

我认为这解决了你的问题,这给出了一个数字列表,如果它们不可用则为0,如果可用则为1

如果您只想要那些可用的那些:

    select Number
      from Table
  group by Number
    having sum(quantity) >= 0

然而,问题在于,根据您的描述,这可能会起作用。在情况下,如果第一个S1有一个进入交易(1)然后一个出局(-1),那么它将被认为是可用的。

所以我不确定SUM方法在你的情况下是否可行。问题是你的要求并不是很清楚。

如果你的例子是:

ID                                               Number         Quantity
45F39260-C646-4CDF-8FC9-E8A2C4B93B9D                S1           1  
F5B033A4-0294-4069-A4D4-9DDBD7D1915D                S2          -1
B94CDB62-9B8B-4C8A-983C-BD896181FEEA                S3           1
98F39260-C646-4CDF-8FC9-E9A2C4B93CH7                S1          -1

会认为S1可用吗?如果是,我的方法(使用> =)有效。

如果没有,则SUM无法解决此问题,但必须检查最后的数量更改。你需要一个发生时间的日期时间/行转换字段并执行select top 1 ..... order by ....来获取可用数字。但是,如果你没有datetime / rowversion字段,那么你想要做的是不可能的,因为数据中没有顺序,因为看起来,你的ID是GUID,而不是顺序guid ....

好的,所以这应该可以解决问题:

     select Number
       from YourTable as prim
   group by Number
        having sum(quantity) >= case when (select top 1 quantity 
                                             from #test as sec
                                            where sec.number = prim.number
                                         order by dt desc) > 0 then 0
                                     else 1 end

PS 老实说,那太乱了。为什么不使用触发器和可用性表? 如果有大量的交易,那么你当前使用总和等的解决方案会变得越来越慢,而且会变得一团糟。