如果我有一个看起来像这样的表:
+---------------------------------------------------+
| SalesPerson | SalesYear | SalesMonth | TotalSales |
+-------------+-----------+------------+------------|
| Dave | 2011 | 1 |27 |
| Meg | 2012 | 7 |162 |
| Randy | 2011 | 3 |0 |
| Julio | 2013 | 8 |15 |
| Bob | 2014 | 12 |0 |
| Mary | 2012 | 5 |20 |
+---------------------------------------------------+
我想找到不活动的时期,让我们说至少连续三个月销售人员没有销售,我该怎么做?我不想要一份没有销售的所有月份的清单;我需要看到长时间不活动。多个连续的零。我无法弄清楚。
答案 0 :(得分:0)
第一步是将年和月转换为日期时间。 接下来,我们应该在SalesPerson的分区中找到每个不活动时段的左右边界。 然后我们对左边界和右边界进行排序以确定如何连接它们。 最后加入左右边界。
--------------creating test data------------------------------------
declare @t table(SalesPerson varchar(max), SalesYear int, SalesMonth int, TotalSales int)
select replicate('0', 2 - len(cast(3 as varchar))) + '3'
insert into @t(SalesPerson, SalesYear , SalesMonth , TotalSales)
select 'Dave', 2011, 1, 27 union all
select 'Meg', 2012, 7, 162 union all
select 'Randy', 2011, 3, 0 union all
select 'Julio', 2013, 8, 15 union all
select 'Bob', 2014, 12, 0 union all
select 'Mary', 2012, 5, 20 union all
select 'Mary', 2012, 6, 0 union all
select 'Mary', 2012, 7, 0 union all
select 'Mary', 2012, 8, 20 union all
select 'Mary', 2012, 9, 20
-------------------------------------------
;with cte as
(
select SalesPerson
, cast(cast(SalesYear as varchar) + replicate('0', 2 - len(cast(SalesMonth as varchar))) + cast(SalesMonth as varchar) + '01' as datetime) as dt
, TotalSales
, row_number() over (partition by SalesPerson order by cast(cast(SalesYear as varchar) + replicate('0', 2 - len(cast(SalesMonth as varchar))) + cast(SalesMonth as varchar) + '01' as datetime)) as rn
, row_number() over (partition by SalesPerson order by cast(cast(SalesYear as varchar) + replicate('0', 2 - len(cast(SalesMonth as varchar))) + cast(SalesMonth as varchar) + '01' as datetime) desc) as rnd
from @t
),
l as
(
select *, row_number() over(partition by SalesPerson order by dt) n
from cte t1
where TotalSales = 0
and (
exists
(
select *
from cte
where t1.SalesPerson = SalesPerson
and dateadd(mm,-1, t1.dt) = dt
and TotalSales > 0
)
or rn = 1
)
),
r as
(
select *,row_number() over(partition by SalesPerson order by dt) n
from cte t1
where TotalSales = 0
and (
exists
(
select *
from cte
where t1.SalesPerson = SalesPerson
and dateadd(mm,1, t1.dt) = dt
and TotalSales > 0
)
or rnd = 1
)
)
select l.SalesPerson, l.dt as dateStart, r.dt as dateEnd
from l
join r on l.n = r.n
and l.SalesPerson = r.SalesPerson
答案 1 :(得分:0)
您对不活动时段的定义有点模糊,例如:你考虑租用/开火日期吗?以下代码实现了一种不需要递归的解释。
-- Sample data.
declare @Sales as Table (
SalesPerson VarChar(10), SalesYear Int, SalesMonth Int, TotalSales Int );
insert into @Sales ( SalesPerson, SalesYear, SalesMonth, TotalSales ) values
( 'Dave', 2011, 1, 27) ,
( 'Meg', 2012, 7, 162 ),
( 'Randy', 2011, 3, 0 ),
( 'Julio', 2013, 8, 15 ),
( 'Bob', 2014, 12, 0 ),
( 'Mary', 2012, 5, 20 ),
( 'William', 2014, 1, 30 ),
( 'William', 2014, 2, 0 ),
( 'William', 2014, 4, 10 ),
( 'William', 2014, 6, 3 ),
( 'William', 2014, 7, 90 ),
( 'William', 2014, 12, 5 );
select * from @Sales;
-- Analyze it.
with
-- Get only the nonzero sales rows and combine the year/month into a single integer.
NonZeroSales as (
select SalesPerson, SalesYear * 12 + SalesMonth as CombinedMonth, TotalSales
from @Sales
where TotalSales <> 0 ),
-- Add row numbers for each sales person.
NonZeroSalesWithRN as (
select SalesPerson, CombinedMonth, TotalSales,
Row_Number() over ( partition by SalesPerson order by CombinedMonth ) as RN
from NonZeroSales )
-- Match adjacent rows for each sales person.
-- If there is a gap of three or more months then indicate it in a status column.
select L.SalesPerson,
Floor( L.CombinedMonth / 12 ) as SalesYear, L.CombinedMonth % 12 as SalesMonth,
L.TotalSales,
case when R.CombinedMonth - L.CombinedMonth > 3 then 'Gap > 3 Months' else 'Okay' end as SalesStatus
from NonZeroSalesWithRN as L inner join
NonZeroSalesWithRN as R on R.SalesPerson = L.SalesPerson and R.RN = L.RN + 1;
-- Tip: To see what is going on, or debug, multiple CTEs replace the last select with
-- select * from NonZeroSales
-- select * from NonZeroSalesWithRN
答案 2 :(得分:-1)