3

我正在尝试制作这样的表格:

产品名称 | 销售截止日期 | TotalSalesUntilDate

    A     |      5    |      15

    B     |     10    |      30

    C     |     20    |      25

    D     |     18    |      43

SalesByDate 表示输入日期每个产品的销售数量,TotalSalesUntilDate 表示每个产品从当月的第一个日期到输入日期的销售数量(输入日期示例:2010 年 3 月 17 日)

我使用子查询编写了这个查询:

    select p.ProductName, A.SalesByDate,
      (select(SUM(case when (pd.Date between '01' and @Date) 
      then s.SalesByDate else 0 end)) 
    from Period pd 
    inner join Sales s on pd.TimeID = s.TimeID 
    full join Product p on s.ProductID = p.ProductID) as TotalSalesUntilDate 
    from Product p join 
         (select s.ProductID, pd.Date, s.SalesByDate
          from Period pd join Sales s on pd.TimeID = s.TimeID) A on 
    p.ProductID = A.ProductID where @Date = A.Date

但我得到了结果:

产品名称 | 销售截止日期 | TotalSalesUntilDate

     A    |     5     |      113

     B    |    10     |      113

     C    |    20     |      113

     D    |    18     |      113

其中 TotalSalesUntilDate 显示了从当月的第一个日期到输入日期的销售产品数量,但对于所有产品,每个产品没有分开。

因此,当我尝试将查询更改为这样时(在“作为 TotalSalesUntilDate”之前添加 GROUP BY p.ProductID):

   select p.ProductName, A.SalesByDate,
     (select(SUM(case when (pd.Date between '01' and @Date) 
     then s.SalesByDate else 0 end)) 
   from Period pd 
     inner join Sales s on pd.TimeID = s.TimeID 
     full join Product p on s.ProductID = p.ProductID 
     group by p.ProductID) as TotalSalesUntilDate 
  from Product p join 
     (select s.ProductID, pd.Date, s.SalesByDate
     from Period pd join Sales s on pd.TimeID = s.TimeID) A on 
    p.ProductID = A.ProductID where @Date = A.Date

当我执行这个查询时,我收到了这个错误消息:

“消息 512,级别 16,状态 1,过程 SalesMTDSubQuery,第 7 行子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 或使用子查询时,这是不允许的作为一种表达。”

由于我是 SQL 新手并且仍在学习,但我不明白如何解决这个问题。任何帮助将不胜感激。谢谢你。

4

2 回答 2

3

@Date变量中,我们存储日期:

SELECT DISTINCT PT.[ProductName]
      ,SUM(IIF(PD.[Date] = @Date, SL.[SalesByDate], 0)) 
      ,SUM(IIF(PD.[Date] BETWEEN '01' AND @Date, SL.[SalesByDate], 0)) 
FROM @Product PT
INNER JOIN @Sales SL
    ON PT.[ProductID] = SL.[ProductID]
INNER JOIN @Period PD
    ON SL.[TimeID] = PD.[TimeID]
GROUP BY PT.[ProductName]

结果:

在此处输入图像描述

完整代码:

DECLARE @Period TABLE
(
     [TimeID] TINYINT
    ,[Date] CHAR(2)
)

INSERT INTO @Period([TimeID], [Date])
VALUES   (1,'01')
        ,(2,'02')
        ,(3,'03')
        ,(4,'04')
        ,(5,'05')
        ,(6,'06')
        ,(7,'07')
        ,(8,'08')
        ,(9,'09')
        ,(10,'10')
        ,(11,'11')
        ,(12,'12')
        ,(13,'13')
        ,(14,'14')
        ,(15,'15')

DECLARE @Product TABLE
(
     [ProductID] TINYINT
    ,[ProductName] CHAR(1)
)

INSERT INTO @Product( [ProductID], [ProductName])
VALUES (1,'A')
      ,(2,'B')
      ,(3,'C')
      ,(4,'D')

DECLARE @Sales TABLE
(
     [TimeID] TINYINT
    ,[ProductID] TINYINT
    ,[SalesByDate] TINYINT
)

INSERT INTO @Sales ([TimeID], [ProductID], [SalesByDate])
VALUES   (1, 1, 10)
        ,(1, 4, 20)
        ,(7, 2, 10)
        ,(7, 3, 5)
        ,(15, 1, 5)
        ,(15, 2, 10)
        ,(15, 3, 15)
        ,(15, 4, 18)
        ,(19, 2, 15)
        ,(20, 3, 2)
        ,(22, NULL, 2)
        ,(1, 4, 5)
        ,(7, 2, 10)
        ,(15, 3, 5)

DECLARE @Date CHAR(2) = '15'

SELECT DISTINCT PT.[ProductName]
      ,SUM(IIF(PD.[Date] = @Date, SL.[SalesByDate], 0)) 
      ,SUM(IIF(PD.[Date] BETWEEN '01' AND @Date, SL.[SalesByDate], 0)) 
FROM @Product PT
INNER JOIN @Sales SL
    ON PT.[ProductID] = SL.[ProductID]
INNER JOIN @Period PD
    ON SL.[TimeID] = PD.[TimeID]
GROUP BY PT.[ProductName]

编辑:

如果您需要使用子查询,这就是您的示例的工作方式:

SELECT PT.[ProductName]
      ,SUM(SL.[SalesByDate])
      ,DataSource.[TotalSalesByDate]
FROM @Product PT
INNER JOIN @Sales SL
    ON PT.[ProductID] = SL.[ProductID]
INNER JOIN @Period PD
    ON SL.[TimeID] = PD.[TimeID]
INNER JOIN 
(
    SELECT S.[ProductID]
          ,SUM(S.[SalesByDate]) AS [TotalSalesByDate]
    FROM @Sales S
    INNER JOIN @Period P
        ON S.[TimeID] = P.[TimeID]
    WHERE P.[Date] BETWEEN '01' AND @Date 
    GROUP BY S.[ProductID] 
) AS DataSource
ON PT.[ProductID] = DataSource.[ProductID]
WHERE PD.[Date] = @Date
GROUP BY PT.[ProductName]
     ,DataSource.[TotalSalesByDate]
于 2013-11-11T07:45:57.180 回答
1

首先,在Table Period你必须有日期,而不是'01','02'你可以使用BETWEEN. 或者你可以使用1,2,3 ...,但它们必须是数字。

因此,我们假设在表中Table Period您有日期数字(我之所以这么说,是因为您使用01, 而不是1假定字符串值。查询本身相对容易:

SELECT 
  p.ProductName, 
  SUM(CASE WHEN s.TimeID = 10 THEN s.SalesByDate ELSE 0 END) as SalesByDate, 
  SUM(CASE WHEN s.TimeID = 10 THEN 0 ELSE s.SalesByDate END) as TotalSalesUntilDate 
FROM 
  Product p 
  INNER JOIN Salse s ON p.ProductID = s.ProductID 
WHERE 
  s.TimeID BETWEEN 1 AND 10
GROUP BY p.ProductName;

您为每个日期进行销售。如果这是一个选定的日期,则将销售额添加到列SalesByDate,否则添加到列TotalSalesUntilDate。你分组ProductName计算SUMWHERE并仅选择在子句中所需期间的日期。我们假设此查询仅针对特定月份启动(因为我们仅使用日期元素 - 即 1,2,...不是月份)。

这将仅显示有销售额的产品。如果您想查看所有产品列表,请使用LEFT JOIN而不是INNER JOIN.

于 2013-11-11T06:16:52.633 回答