当大小范围有一个或多个大于0的值时返回结果

时间:2014-06-20 09:53:25

标签: sql sql-server-2008-r2 group-by sum

我有一个分类帐条目表用于计算物料库存(其中销售和退货总计为计算当前库存)。

使用以下方法对此数量列求和似乎非常简单:

select [Item Ledger].[Location],[Item].[Item Division Code],
[Ledger Entry].[Item],[Variant Code],
SUM([Item Ledger].[Quantity]) as 'stock'
from [Item Ledger]
join [Item] on [Ledger Entry].[Item] = [Item].[no_]
where [Item Ledger].[Location Code] = 'xx'
group by [Item Ledger].[Location],[Item Ledger].[Item],
[Variant Code],[Item].[Item Division Code]
order by [Item Ledger Entry].[Item]

我想看到的是一个列表,其中该商品可能有1个或多个库存变种,但其他变种可能有0个库存。目前我可以退回所有0库存/所有库存或所有具有价值的库存。我看不到如何返回包含零和值的变体的项目(但排除所有仅对变体有0的项目)

例如

我可能有一件衬衫(衬衫1),其中包括变体代码(尺寸)小,中(m),大(l) 运行上面的代码,它可能显示我有2个小型,1个中型和0个大型库存

它也可以显示为shirt2我有0小,0中等和0大

我想看到的只是shirt1,因为我对整个尺码范围内只有0个值的样式不感兴趣。

1 个答案:

答案 0 :(得分:0)

好的,我想我明白了这个问题。现在您的数据如下:

Item      Varient     Stock
Shirt1        S           2
Shirt1        M           1
Shirt1        L           0
Shirt2        S           0
Shirt2        M           0
Shirt2        L           0
Shirt3        M           2
Shirt4        L           0
Shirt5        S           1
Shirt5        M           2
Shirt5        L           4

但是,您只需要Shirt1的数据。你对shirt3或shirt4不感兴趣,因为只有一个变种,所以它们不合适。你不需要衬衫2,因为没有任何库存,你不需要衬衫5,因为没有任何缺货。这是我推荐的方法:

select  il.Location,
        i.ItemDivisionCode,
        il.Item,
        VariantCode,
        SUM(il.Quantity) as 'stock'
 from ItemLedger il
 join Item i
    on il.Item = i.no_
where il.LocationCode = 'xx'
and Case When ( Select sum(1)
                 From ItemLedger il2
                Where   il2.item = il.item
                 and    il2.quantity = 0
                Group by il2.item) > 0
    Then ISNULL(
                    (Select sum(1)
                      From  ItemLedger il2
                     Where  il2.item = il.item
                      and   il2.quantity > 0
                     Group by il2.item)
                , 0)
    Else 0
    End > 0

group by    il.Location,
            il.Item,
            VariantCode,
            i.ItemDivisionCode
order by il.Item

现在,让我们来谈谈这个查询的含义。首先,我抓住了您发布的查询并添加了别名。别名实质上是给表一个昵称。您可以使用别名而不是一遍又一遍地引用表名,而sql会知道您在说什么。

现在,您正在寻找的内容是在where子句中,即case语句。 case语句本质上是if... then... else...语句的sql版本。案例陈述的第一部分是条件。

Case When ( Select sum(1)
                     From ItemLedger il2
                    Where   il2.item = il.item
                     and    il2.quantity = 0
                    Group by il2.item) > 0

在这种情况下,条件是子查询。此子查询在项目legder表中查找与我们当前查看的行相同类型的所有项目,其中0为库存数量。因此,对于shirt1,此子查询将返回1.对于shirt2,此子查询将返回3.现在条件部分进入。如果我们返回的值大于0,我们将继续返回到下一个案件陈述的一部分。

Then ISNULL(
            (Select sum(1)
              From  ItemLedger il2
             Where  il2.item = il.item
              and   il2.quantity > 0
             Group by il2.item)
            , 0)

现在我们要查看库存中有多少种变种。对于shirt1,此子查询将撤回2.对于shirt2,此查询将撤回null。为什么?好吧,子查询说要计算有多少行的数量大于0.Bask2没有任何数量大于0的行。如果我们要运行子查询本身,我们就是不会得到任何信息。你怎么能不总结信息?幸运的是,我们可以解决这个问题。 ISNULL说,如果此查询没有带回任何内容,我们只是说它带回了0。

如果我们的case语句的'if'部分返回为false,会发生什么?我们不会去案例陈述的“当时”部分,而是前往这里:

Else 0

这确实只是说将0作为数字返回。然后,我们完成了案例陈述,因为我们已经覆盖了所有的基础。现在,我们尚未完全完成。 case语句包含在where子句中。我们已经说过了

and --the case statement

where子句中的所有内容都必须返回true或false,我们无法评估and 0and 12。因此,我们必须对我们刚刚发现的信息做一些事情,以使结果成为布尔值。我们通过要求case语句的结果大于0来做到这一点。我现在肯定你在想“这会有用吗?”

实际上它会。这就是原因。如果该项目没有库存为0的varient,我们将从案例中得到0并且规则为out(因为0不大于0)。如果该项具有库存0的变量,我们将检查它们是否具有库存大于0的东西。如果它们没有,我们仍然返回0并将其排除在外。

对于一个简单的问题,这似乎是一个错综复杂的答案,但实际上问题并非如此简单。您询问有关不同数据点的信息。你要做的就是问你的朋友乔,史蒂夫今晚要去看电影。乔对史蒂夫一无所知。获取这些信息的唯一方法是联系史蒂夫并找出他的信息。子查询基本上是通过从完全不同的select语句中提取数据来实现的。