2010-06-30 109 views
0

这个问题是基于从另一个SO question, can be found here得到的答案。sql查询再次销售汇总

我已成功地编写一个查询自己基于答案只要

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的破损率为2,870的Refund为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] 

更新的查询
我添加Products表参考,并呈现出所需的输出,但其显示所有产品是否有任何出售或断裂或发生退款或没有在该日期。

我不想在没有销售或没有损坏或没有退款的情况下显示行。这会减少我的报告大小。当前显示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; 
+0

你真的需要找到一种方法来写你的T-SQL更易读,更平易近人的方式!这只是一个巨大的,难以阅读和难以理解的角色混乱...... – 2010-06-30 16:15:09

+1

@marc_s:有时候我会考虑让它保持原样,并且对这个问题的可读性做出评论意味着它更可能获得帮助... – 2010-06-30 16:23:17

回答

1

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

注:

  1. 这是更有效的使用>或<代替=如果你能!这就是为什么我改变了p.pGroup上的谓词。 (我假设没有15至16岁的小组)。
  2. 所有灌溉都是在APPLY子查询中完成的,因此您不需要再使用GROUP BY子句。

这里是更新查询:

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 
      ) 
+0

没有显示任何结果(0行) – 2010-07-01 07:58:59

+0

嗨乔恩佩恩我找到了实现我的目标的新方法。我创建了一个临时表,其中添加了这些数据,然后删除了其值sals,破损和退款值为0的行。 – 2010-07-01 13:21:28

+0

查询不起作用,因为我设置了BillDate错误?我将它设置为'12-10 2010'而不是'12-10-2010'? – JonPayne 2010-07-01 13:50:50

1

你的子查询,如此,将总是得到相同的数据的每一行,因为where子句不引用外部查询中的任何内容。

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

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

+0

正确 - 这是相关和不相关子查询之间的区别。无论返回多少行,不相关的子查询结果都不会改变。 – 2010-06-30 16:32:04

0

子查询应该使用where子句引用主查询。将te sum与SalesLog.ProductCode关联起来,我想。为了更准确的答案,你应该发布表结构。

+0

有产品破损和没有销售时可能有条件,那么它不会显示破损。早些时候,我对SalesLog.Product代码有相同的参考。谢谢 – 2010-06-30 16:37:37

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 ; 
+0

你好乔恩佩恩,我已根据当前情况更新我的问题与查询。您的查询没有显示任何输出,所以我添加了产品表参考,现在显示所有产品的详细信息。我现在想要只显示出现任何销售或破损或退款的产品。例如 A有10个销售0突破0退款 - >它会显示 B有0销售10个破发0退款 - >它会显示 C具有0销售0突破0退款 - >它不会显示 感谢 – 2010-07-01 05:25:30

+0

你没有提及产品表 - 我正在提供您提供的信息。 – JonPayne 2010-07-01 06:43:48