sql再次查询销售摘要

时间:2010-06-30 16:13:24

标签: sql sql-server tsql

这个问题是基于另一个SO question, can be found here的回答。

我已经设法自己编写了一个基于

的答案
   Select s.pName, 
       s.ProductCode, 
       min(s.Price)                         as MinPrice, 
       sum(s.Quantity)                      as SalesQty, 
       sum(s.Price * s.Quantity)            as SalesValue, 
       isnull((select sum(Quantity) 
               from   Breakages 
               where  pGroup = 16 
                      and quantity > 0), 0) as BreakQty, 
       isnull((select sum(Price * Quantity) 
               from   Breakages 
               where  pGroup = 16), 0)      as BreakValue, 
       isnull((select CASE 
                        WHEN min(r.Quantity) != 0 THEN Sum(r.Quantity) 
                      END), 0)              as ReturnQty, 
       isnull((select sum(Price * Quantity) 
               from   SalesReturn 
               where  pGroup = 16), 0)      as ReturnValue 
from   SalesLog as s 
       INNER JOIN SalesReturn as r 
         ON r.BillDate = s.BillDate 
       INNER JOIN Breakages as b 
         ON r.BillDate = b.BillDate 
where  s.BillDate = '12-10-2010' 
       and r.BillDate = '12-10-2010' 
       and b.BillDate = '12-10-2010' 
       and s.pGroup = 16 
       and b.pGroup = 16 
       and r.pGroup = 16 
group  by s.pName, 
          s.ProductCode; 

以下是上述查询的输出

Name               Code Price SalesQty SValue  BreakQty BValue  RefundQty  RQty
CDM 42GRMS.        854    15      3       45        2       0         3     30
APPLE JUICE 750ML  860    59      5      295        2       0         3     30
BISLERI WATER      865     3      5       15        2       0         3     30
PERK 35 GRMS       870    10     20      200        2       0         3     30

输出存在问题,因为您可能无法获得,Code = 865的Breakages为2,而870的退款为3,但所有行都有破损和退款。

您可以在我的查询中找到实验。 谢谢........等待回复

SalesRetrun表

CREATE TABLE [dbo].[SalesReturn](
    [srID] [int] IDENTITY(1,1) NOT NULL,
    [ProductCode] [int] NULL,
    [Quantity] [int] NULL,
    [pGroup] [int] NULL,
    [MemoNo] [int] NULL,
    [SalesmanID] [int] NULL,
    [Price] [int] NULL,
    [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [AddedOn] [datetime] NULL,
 CONSTRAINT [PK_SalesReturn] PRIMARY KEY CLUSTERED 
([srID] ASC) WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

SalesLog表

CREATE TABLE [dbo].[SalesLog](
   [SalesID] [int] IDENTITY(1,1) NOT NULL,
   [MemoNo] [int] NULL,
   [ProductCode] [int] NULL,
   [Quantity] [int] NULL,
   [Price] [int] NULL,
   [pGroup] [int] NULL,
   [pName] [nvarchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
   [pSize] [int] NULL,
   [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
 CONSTRAINT [PK_SalesLog] PRIMARY KEY CLUSTERED 
 (  [SalesID] ASC )WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 ) ON [PRIMARY]

破损表

CREATE TABLE [dbo].[Breakages](
    [breakId] [int] IDENTITY(1,1) NOT NULL,
    [MemoNo] [int] NULL,
    [SalesmanID] [int] NULL,
    [ProductCode] [int] NULL,
    [pName] [nvarchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [Quantity] [int] NULL,
    [Price] [int] NULL,
    [pGroup] [int] NULL,
    [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [AddedOn] [datetime] NULL,
 CONSTRAINT [PK_Breakages_1] PRIMARY KEY CLUSTERED (
[breakId] ASC )WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

更新查询
我已经添加了产品表参考,并显示了所需的输出,但它显示了所有产品是否发生了任何销售或中断或退款。

我不希望在没有销售或没有破损或不退款的情况下显示行。这会减少我的报告大小。当前显示319行,但根据我的逻辑删除行(手动计算)后,它减少到16行(假数据)

SELECT  p.pName, p.pCode, MIN(p.pPrice) AS MinPrice
   , SUM(s.Quantity) AS SalesQty, SUM(s.Quantity) * MIN(p.pPrice) AS SalesValue
   , MIN(b.Quantity) AS BreakQty, MIN(b.Quantity) * MIN(p.pPrice) AS BreakValue
   , MIN(r.Quantity) AS ReturnQty, MIN(r.Quantity) * MIN(p.pPrice) AS ReturnValue
FROM    Products AS p

OUTER APPLY (SELECT SUM(s.Quantity) AS Quantity
         FROM   SalesLog AS s
         WHERE  s.BillDate = '12-10-2010'
                AND s.ProductCode = p.pCode
        ) AS s
OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity
         FROM   SalesReturn AS r
         WHERE  r.BillDate = '12-10-2010'
                AND r.ProductCode = p.pCode
        ) AS r
OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity
         FROM   Breakages AS b
         WHERE  b.BillDate = '12-10-2010'
                AND b.ProductCode = p.pCode
        ) AS b
WHERE  p.pGroup!=15 and p.pGroup!=16 
GROUP BY p.pName, p.pCode;

4 个答案:

答案 0 :(得分:1)

您的子查询(如此)将始终为每一行获取相同的数据,因为where子句不引用外部查询中的任何内容。

   isnull((select sum(Quantity) 
           from   Breakages 
           where  pGroup = 16 
                  and quantity > 0), 0) as BreakQty

我没时间弄清楚应该是什么。

答案 1 :(得分:1)

由于我不知道您的数据,因此很难给出准确的答案。但是,我认为你正在追求以下方面:

SELECT  s.pName
      , s.ProductCode
      , MIN(s.Price) AS MinPrice
      , SUM(s.Quantity) AS SalesQty
      , SUM(s.Quantity) * MIN(s.Price) AS SalesValue
      , MIN(b.Quantity) AS BreakQty
      , MIN(b.Quantity) * MIN(s.Price) AS BreakValue
      , MIN(r.Quantity) AS ReturnQty
      , MIN(r.Quantity) * MIN(s.Price) AS ReturnValue
FROM    SalesLog AS s
OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity
             FROM   @SalesReturn AS r
             WHERE  r.BillDate = s.BillDate
                    AND r.ProductCode = s.ProductCode
            ) AS r
OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity
             FROM   @Breakages AS b
             WHERE  b.BillDate = s.BillDate
                    AND b.ProductCode = s.ProductCode
            ) AS b
WHERE   s.BillDate = '12-10 2010'
GROUP BY s.pName
      , s.ProductCode ; 

答案 2 :(得分:1)

你正在移动目标职位!但是,以下是您更新问题的可能解决方案。

注意:

  1. 使用>效率更高或者<而不是!=如果可以的话。这就是为什么我改变了p.pGroup上的谓词。 (我假设15到16之间没有小组)。
  2. 所有灌溉都在APPLY子查询中完成,因此您不再需要GROUP BY子句。
  3. 以下是更新的查询:

    SELECT  p.pName
          , p.ProductCode
          , p.Price AS MinPrice
          , s.Quantity AS SalesQty
          , s.Quantity * p.Price AS SalesValue
          , b.Quantity AS BreakQty
          , b.Quantity * p.Price AS BreakValue
          , r.Quantity AS ReturnQty
          , r.Quantity * p.Price AS ReturnValue
    FROM    Products AS p
    OUTER APPLY (SELECT SUM(s.Quantity) AS Quantity
                 FROM   SalesLog AS s
                 WHERE  s.BillDate = '12-10 2010' 
                        AND s.ProductCode = p.ProductCode
                ) AS s
    OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity
                 FROM   SalesReturn AS r
                 WHERE  r.BillDate = '12-10 2010' 
                        AND r.ProductCode = p.ProductCode
                ) AS r
    OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity
                 FROM   Breakages AS b
                 WHERE  b.BillDate = '12-10 2010' 
                        AND b.ProductCode = p.ProductCode
                ) AS b
    WHERE   p.pGroup < 15
            AND p.pGroup > 16
            AND (
                 s.Quantity IS NOT NULL
                 OR r.Quantity IS NOT NULL
                 OR b.Quantity IS NOT NULL
                )   
    

答案 3 :(得分:0)

子查询应引用主查询,并带有where子句。我认为将te sum与SalesLog.ProductCode联系起来。要获得更准确的答案,您应该发布表格结构。