复合SP用于每月销售返回错误数据

时间:2014-03-10 06:01:29

标签: sql sql-server-2008 stored-procedures reporting

我将尝试解释这个问题,并简化了在此过程中重要的两个必需表:

**Table 1: book_sales**
identifiers
sales_price
sales_date
store
quantity

**Table2: discount**
identifiers
sales_price (the changed / discounted price)
from_date
to_date
  • 如果to_date表格中的Discount为“2999-01-01”,则应覆盖sales price中的book_sales(在此示例中为:99, - )
  • 如果from_date表格中的to_dateDiscount只是一段时间,请说FromDate:2014-02-03和To_Date 2014-02-05它应该覆盖另一个正是那个时期的价格。 (在这个例子中它是69, - )

我的存储过程应该返回如下数据:

+------------+-----------+---------+----+-----+
| 2014-02-01 |  ItemName |  Item01 |  3 |  99 |
| 2014-02-02 |  ItemName |  Item01 |  2 |  99 |
| 2014-02-03 |  ItemName |  Item01 |  2 |  69 |
| 2014-02-04 |  ItemName |  Item01 |  2 |  69 |
| 2014-02-05 |  ItemName |  Item01 |  2 |  69 |
| 2014-02-06 |  ItemName |  Item01 |  2 |  99 |
+------------+-----------+---------+----+-----+

但是它显示了这两个并返回这样的数据:

+------------+-----------+---------+----+-----+
| 2014-02-01 |  ItemName |  Item01 |  3 |  99 |
| 2014-02-01 |  ItemName |  Item01 |  3 |  69 |
| 2014-02-02 |  ItemName |  Item01 |  2 |  99 |
| 2014-02-02 |  ItemName |  Item01 |  2 |  69 |
| 2014-02-03 |  ItemName |  Item01 |  2 |  99 |
| 2014-02-03 |  ItemName |  Item01 |  2 |  69 |
+------------+-----------+---------+----+-----+

...等 所以这是实际的程序,你们有没有看错?

ALTER PROCEDURE [dbo].[Loid] @month         INT, 
                             @year          INT, 
                             @report_source NVARCHAR(255), 
                             @is_primary    INT 
AS 
    SELECT Cast(isa.sales_date AS DATE)                                   AS 
           DATE, 
           BV.name, 
           isa.identifiers, 
           isa.quantity, 
           Isnull(id.sales_price, Isnull(u.sales_price, isa.sales_price)) AS 
           SALES_PRICE 
    FROM   book_sales AS isa 
           INNER JOIN store AS BV 
                   ON bv.store_id = isa.store_id 
           LEFT OUTER JOIN discount AS id 
                        ON id.identifiers = isa.identifiers 
                           AND id.from_date <= isa.sales_date 
                           AND id.to_date >= isa.sales_date 
                           AND id.to_date < '2999-01-01' 
                           AND BV.name = id.store 
           LEFT OUTER JOIN discount AS u 
                        ON u.identifiers = isa.identifiers 
                           AND u.to_date = '2999-01-01' 
           LEFT OUTER JOIN book_contributor AS BC 
                        ON BC.book_id = isa.book_id 
    WHERE  Month(isa.sales_date) = @month 
           AND Year(isa.sales_date) = @year 
           AND isa.report_source = @report_source 
           AND bc.is_primary = @is_primary 

1 个答案:

答案 0 :(得分:2)

通过查看结果,我假设您已将from_date值设置为折扣记录,其中包含to_date'2999-01-01'

LEFT OUTER JOIN discount AS id 
ON id.identifiers = isa.identifiers 
AND id.from_date <= isa.sales_date 
AND id.to_date >= isa.sales_date 

如果在此连接语句中如此,那些折扣记录也会加入,从而创建重复记录。

您可以将from_date设置为更高的值,例如'2999-01-01',以获取折扣记录,其中包含to_date'299-01-01'或更改连接状态,如下所示。

LEFT OUTER JOIN discount AS id 
ON id.identifiers = isa.identifiers 
AND id.from_date <= isa.sales_date 
AND id.to_date >= isa.sales_date 
AND id.to_date < '2999-01-01'

修改

根据聊天以下应该工作。新条件 BV.name = u.store 将添加到带折扣表的第二次加入。

ALTER PROCEDURE [dbo].[Loid] @month         INT, 
                             @year          INT, 
                             @report_source NVARCHAR(255), 
                             @is_primary    INT 
AS 
    SELECT Cast(isa.sales_date AS DATE)                                   AS 
           DATE, 
           BV.name, 
           isa.identifiers, 
           isa.quantity, 
           Isnull(id.sales_price, Isnull(u.sales_price, isa.sales_price)) AS 
           SALES_PRICE 
    FROM   book_sales AS isa 
           INNER JOIN store AS BV 
                   ON bv.store_id = isa.store_id 
           LEFT OUTER JOIN discount AS id 
                        ON id.identifiers = isa.identifiers 
                           AND id.from_date <= isa.sales_date 
                           AND id.to_date >= isa.sales_date 
                           AND id.to_date < '2999-01-01' 
                           AND BV.name = id.store 
           LEFT OUTER JOIN discount AS u 
                        ON u.identifiers = isa.identifiers 
                           AND u.to_date = '2999-01-01'
                           AND BV.name = u.store  
           LEFT OUTER JOIN book_contributor AS BC 
                        ON BC.book_id = isa.book_id 
    WHERE  Month(isa.sales_date) = @month 
           AND Year(isa.sales_date) = @year 
           AND isa.report_source = @report_source 
           AND bc.is_primary = @is_primary