我正在解决一个问题,因为他知道一个号码是否可用。
例如,我有一个存储交易的表,如果交易是传出的,我们将数量存储为负数,如果它存在,则我们将其存储为正数量。
在开始时我认为,如果数量大于零,则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
答案 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 老实说,那太乱了。为什么不使用触发器和可用性表? 如果有大量的交易,那么你当前使用总和等的解决方案会变得越来越慢,而且会变得一团糟。