2016-12-07 54 views
0

我在表中记录了所有分支机构的所有销售额的以下数据。我需要弄清楚这家店是卖它的产品比别人快,使我们可以决定要发送的库存到存储SQL - 在哪个商店查询中查找哪个产品销售得更快

样本数据:

 
Ref | Colour | Size | Branch | QtySold | DatePosted 
| BLU | 01 | ABC | 1  | 2016-08-01 17:37:29.310 
| BLU | 01 | CFR | 1  | 2016-08-01 17:37:29.310 
| BLU | 01 | CFD | 2  | 2016-08-01 17:37:29.310 
021456 | YEL | 06 | ABC | 5  | 2016-08-02 17:37:29.310 
021456 | YEL | 06 | AMC | 2  | 2016-08-02 15:37:29.310 

我写了下面的SP,它接受没有fromdate和todate和其他参数。

ALTER PROCEDURE [dbo].[GetSalesByDate] 
(
    @FromDate datetime = NULL, 
    @ToDate datetime = NULL, 
    @Ref nvarchar(MAX) = NULL, 
    @ColourCode nvarchar(20) = NULL, 
    @StoreCode nvarchar(6) = NULL, 
    @SizeIndex nvarchar(3) = NULL 
) 

AS 
BEGIN 

SELECT 
YEAR(S.DatePosted) 'Year', DATEPART(week,S.DatePosted) NumberOfTheWeek, 
S.Ref, 
S.Colour ColourCode, 
S.Sno SizeIndex, 
S.Branch StoreCode, 
DATEDIFF(day,@FromDate, @ToDate) TotalDays, 
SUM(S.Qty) QtyPerUnit 

FROM SalesHistory S 

WHERE 
(S.DatePosted BETWEEN @FromDate AND @ToDate) 
AND (S.Ref IN (SELECT * from dbo.SplitList(@Ref, ',')) OR @Ref IS null) 
AND (S.Colour = @ColourCode OR @ColourCode IS null) 
AND (S.Sno = @SizeIndex OR @SizeIndex IS null) 

AND (S.Branch = @StoreCode OR @StoreCode IS NULL) 

GROUP BY 
S.Branch, YEAR(S.DatePosted), DATEPART(week,S.DatePosted),S.Ref,S.Colour,S.Sno 

ORDER BY 
S.Ref, S.Colour 

我觉得上面的SP不回我想要什么...... 我想每个编号,颜色,尺寸(产品)的销售中给出的每一个分支

  1. 比较FromDate和ToDate,返回该期间的数据,并将其与上周和去年同一周进行比较。

任何人都可以在这里帮助请....

结果应该是这样的。

 
Year | No.OfThheWeek | Ref | Colour | Size | Branch | TotalQtySoldForThePeriod | LastWeekTotalQtySold | LastYearTotalQtySold 
2016 | 32   || BLU | 01 | ABC | 125     | 205      | 310 
2016 | 33   || BLU | 01 | ABC | 55     | 155      | 214 
2016 | 33   | 021456 | YEL | 06 | AMC | 74     | 46      | 83 
+1

首先你应该确定你的结果应该是什么样子。请问您可以将样品结果添加到您的请求中吗? –

+0

在我的问题中添加了结果... –

回答

1

首先,您应该更正您当前的查询。 Group通过这么多的列是alwys wrong.Group通过anID列是最好的,那么你可以加入CTE来获得其他列的名称。

AnyWay我假设你当前的查询输出是正确的,那么你可以继续这样的事情。 注:这是突出部分对于理解

declare @Reftbl table(ref varchar(20)) 
insert into @Reftbl 
SELECT col1 from dbo.SplitList(@Ref, ',') 

declare @FromDate datetime = '2016-08-01' , @ToDate datetime = '2016-08-31' 
declare @lastWeekFrom datetime=dateadd(day,-7,@FromDate) 
declare @lastWeekTo datetime=dateadd(day,6,@lastWeekFrom) 
declare @lastYearSameWeekFrom datetime=dateadd(year,-1,@FromDate) 
declare @lastYearSameWeekFromTo datetime=dateadd(day,6,@lastYearSameWeekFrom) 

select @lastWeekFrom , @lastWeekTo,@lastYearSameWeekFrom,@lastYearSameWeekFromTo 
;with CurrentCTE 
(
    SELECT 
YEAR(S.DatePosted) 'Year', DATEPART(week,S.DatePosted) NumberOfTheWeek, 
S.Ref, 
S.Colour ColourCode, 
S.Sno SizeIndex, 
S.Branch StoreCode, 
DATEDIFF(day,@FromDate, @ToDate) TotalDays, 
SUM(S.Qty) QtyPerUnit 

FROM SalesHistory S 

WHERE 
(S.DatePosted BETWEEN @FromDate AND @ToDate) 
AND (S.Ref IN (SELECT ref from @Reftbl) OR @Ref IS null) 
AND (S.Colour = @ColourCode OR @ColourCode IS null) 
AND (S.Sno = @SizeIndex OR @SizeIndex IS null) 

AND (S.Branch = @StoreCode OR @StoreCode IS NULL) 

GROUP BY 
S.Branch, YEAR(S.DatePosted), DATEPART(week,S.DatePosted),S.Ref,S.Colour,S.Sno 

--ORDER BY 
--S.Ref, S.Colour 
) 
,LastWeekCTE 
(
    SELECT 

S.Ref, 
S.Colour ColourCode, 
S.Sno SizeIndex, 
S.Branch StoreCode, 
SUM(S.Qty) LastWeekTotalQtySold 

FROM dbo.SalesHistory S 

WHERE 
(S.DatePosted BETWEEN @lastWeekFrom AND @lastWeekTo) 
AND (S.Ref IN (SELECT ref from @Reftbl) OR @Ref IS null) 
AND (S.Colour = @ColourCode OR @ColourCode IS null) 
AND (S.Sno = @SizeIndex OR @SizeIndex IS null) 

AND (S.Branch = @StoreCode OR @StoreCode IS NULL) 

GROUP BY 
S.Branch, S.Ref,S.Colour,S.Sno 
) 
,LastYearSameWeekCTE 
(
    SELECT 

S.Ref, 
S.Colour ColourCode, 
S.Sno SizeIndex, 
S.Branch StoreCode, 
SUM(S.Qty) LastYearTotalQtySold 

FROM dbo.SalesHistory S 

WHERE 
(S.DatePosted BETWEEN @lastYearSameWeekFrom AND @lastYearSameWeekFromTo) 
AND (S.Ref IN (SELECT ref from @Reftbl) OR @Ref IS null) 
AND (S.Colour = @ColourCode OR @ColourCode IS null) 
AND (S.Sno = @SizeIndex OR @SizeIndex IS null) 

AND (S.Branch = @StoreCode OR @StoreCode IS NULL) 

GROUP BY 
S.Branch, S.Ref,S.Colour,S.Sno 
) 

select c.*,c1.LastWeekTotalQtySold 
,c2.LastYearTotalQtySold 
    from 
CurrentCTE C 
inner join 
LastWeekCTE C1 on c.somecol=c1.somecol 
inner join LastYearSameWeekCTE c2 on c.somecol=c2.somecol 

你可以看到@ Reftbl.so使用表,你不必使用分割功能多次。

+0

“Group by many columns are always wrong。”这是一个笑话,不是吗? –

+0

@ThorstenKettner,我们真的应该避免在这么多列上,如果DB设计许可,它真的是一个非常快捷的方法,性能不好。 – KumarHarsh

+0

我从来没有遇到性能问题,因为列表很大。我从来没有见过任何其他人有这样的问题。毕竟这个清单是有原因的。我们希望每个<列列表>都有一个结果行。如果这是每个分支,年/周,项目,颜色和大小,那么这是列表。 –

1

首先:@FromDate和@ToDate没什么意义,因为显然它们应该是一个星期,你还可以怎样“比较上周和去年同一周”?我认为这里的“last”意思是“previous”,所以我们正在看一些给定的七天,即前一天的七天和七天。所以最好的做法是忽略@ToDate,只需将7天添加到@FromDate中,以确保准确谈论7天。

下面是做到这一点的一种方法:

SELECT 
    ref, colour, size, branch, 
    SUM(CASE WHEN dateposted BETWEEN @FromDate 
          AND DATEADD(day, 7, @FromDate) 
      THEN qty 
     END) AS this_week_qty, 
    SUM(CASE WHEN dateposted BETWEEN DATEADD(day, -8, @FromDate) 
          AND DATEADD(day, -1, @FromDate) 
      THEN qty 
     END) AS previous_week_qty, 
    SUM(CASE WHEN dateposted BETWEEN DATEADD(year, -1, @FromDate) 
            AND DATEADD(day, 7, DATEADD(year, -1, @FromDate)) 
      THEN qty 
     END) AS previous_year_week_qty 
sum(qty) as sum_qty 
FROM saleshistory 
WHERE dateposted BETWEEN @FromDate 
       AND DATEADD(day, 7, @FromDate) -- requested week 
    OR dateposted BETWEEN DATEADD(day, -8, @FromDate) 
       AND DATEADD(day, -1, @FromDate) -- previous week 
    OR dateposted BETWEEN DATEADD(year, -1, @FromDate) 
       AND DATEADD(day, 7, DATEADD(year, -1, @FromDate)) -- week in previous year 
GROUP BY ref, colour, size, branch; 
相关问题