我可以通过视图中的where子句来设置递归cte吗?

but5z9lq  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(351)

我想让这个查询成为一个视图,根据所需的时间框架生成一个递归日期cte。现在,为了本例的目的,我将递归的开始日期固定为2019年12月30日,结束日期固定为2020年1月4日。我知道我没有在视图中设置变量的选项,但是,我想知道是否有一种方法可以间接地做到这一点。有没有办法让起始日期和gen gap结束日期依赖于where子句?
这是查询

WITH Dates AS (
    SELECT [GenGapDate] = CONVERT(DATETIME,'12/30/2019') -- // this is the starting date
    UNION ALL 
    SELECT [GenGapDate] = DATEADD(DAY, 1, [GenGapDate])
    FROM Dates
    WHERE GenGapDate < '1/4/2020'
),
StoreXJoinDate as (
    select  d.[GenGapDate],
            s.Store,
            s.OpenDate,
            s.CloseDate
    from Dates  as d
    cross join #Stores s
),
POSQtySum as (
    select 
            p.SaleDate,
            p.Store,
         sum(p.Qty)  as TotQty
    from #POS p
    group by p.SaleDate, p.Store
),
StoreQty as (
    select  distinct 
            x.GenGapDate,
            x.Store,
            p.Store as PosStore,
            x.OpenDate,
            x.CloseDate,
            isnull(p.TotQty,0) as TotQty
    from StoreXJoinDate x
    full outer join POSQtySum p on  p.Store = x.Store
                                and p.SaleDate = x.GenGapDate
),
BaseResultSet as (
    select  GenGapDate,
            Store,
            OpenDate,
            CloseDate,
            TotQty,
            1 as StoreIsMissing
    from StoreQty
    where TotQty = 0
    and (
            CloseDate is null 
            or (CloseDate >= GenGapDate)
    )
    and OpenDate is not null
    and GenGapDate >= OpenDate
    union
    select  GenGapDate,
   Store,
   OpenDate,
   CloseDate,
   TotQty,
   NULL as StoreIsMissing
    from StoreQty
    where TotQty > 0
)
select  GenGapDate,
        Store,
        OpenDate,
        CloseDate,
        TotQty,
        StoreIsMissing
from BaseResultSet
order by GenGapDate desc, Store asc;

下面是生成用于查询的数据的构建脚本。

create table #Stores  -- drop table #Stores
(Store int,
 OpenDate date,
 CloseDate date
 );

 create table #ProdCat -- drop table #ProdCat
 (ProdCatId int,
  ProdCatName varchar(10)
  );

 create table #POS -- drop table #POS
 (SaleDate date,
  Store int,
  ProdCatId int,
  Qty int
  );

-- Store inserts
insert into #Stores
(Store,OpenDate,CloseDate)
values
(123,'2019-12-31',NULL);

insert into #Stores
(Store,OpenDate,CloseDate)
values
(124,'1995-01-01',NULL);

insert into #Stores
(Store,OpenDate,CloseDate)
values
(125,'2000-01-01','2020-01-03');

-- ProdCat inserts
insert into #ProdCat
(ProdCatId,ProdCatName)
values
(1,'Produce');

insert into #ProdCat
(ProdCatId,ProdCatName)
values
(2,'Diary');

-- POS inserts
insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2019-12-30',1,124,420);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2019-12-30',2,124,180);

-- --

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',1,123,10);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',2,123,10);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',1,124,500);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',2,124,200);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',1,125,50);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-02',2,125,0);

-- --

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-03',1,123,12);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-03',2,123,15);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-03',1,124,510);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-03',2,124,195);

-- --

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-04',1,123,6);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-04',2,123,10);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-04',1,124,610);

insert into #POS
(SaleDate,ProdCatId,Store,Qty)
values
('2020-01-04',2,124,220);
u0njafvf

u0njafvf1#

根据您希望如何使用它,您可以将整个过程转换为表值函数。

create function MissingStores (@startDate date, @endDate date)
returns table
as
return 
  (
        WITH Dates AS (
            SELECT [GenGapDate] = @startDate -- // this is the starting date
            UNION ALL 
            SELECT [GenGapDate] = DATEADD(DAY, 1, [GenGapDate])
            FROM Dates
            WHERE GenGapDate < @endDate
        ),
        StoreXJoinDate as (
       ... <The rest of your query....>
  );

这实际上是SQLServer对参数化视图的实现。从这里开始,您将函数视为一个表,但是使用参数。请注意 ORDER BY 不在功能范围内。函数不支持 ORDER BY 条款。

select *
from MissingStores ('20191230', '20200104')
order by GenGapDate desc, Store asc;

结果(请原谅测试人员的日期格式):

|    |     GenGapDate      | Store |      OpenDate       |      CloseDate      | TotQty | StoreIsMissing |
+----+---------------------+-------+---------------------+---------------------+--------+----------------+
|  1 | 04.01.2020 00:00:00 |   123 | 31.12.2019 00:00:00 | NULL                |     16 | NULL           |
|  2 | 04.01.2020 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |    830 | NULL           |
|  3 | 03.01.2020 00:00:00 |   123 | 31.12.2019 00:00:00 | NULL                |     27 | NULL           |
|  4 | 03.01.2020 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |    705 | NULL           |
|  5 | 03.01.2020 00:00:00 |   125 | 01.01.2000 00:00:00 | 03.01.2020 00:00:00 |      0 | 1              |
|  6 | 02.01.2020 00:00:00 |   123 | 31.12.2019 00:00:00 | NULL                |     20 | NULL           |
|  7 | 02.01.2020 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |    700 | NULL           |
|  8 | 02.01.2020 00:00:00 |   125 | 01.01.2000 00:00:00 | 03.01.2020 00:00:00 |     50 | NULL           |
|  9 | 01.01.2020 00:00:00 |   123 | 31.12.2019 00:00:00 | NULL                |      0 | 1              |
| 10 | 01.01.2020 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |      0 | 1              |
| 11 | 01.01.2020 00:00:00 |   125 | 01.01.2000 00:00:00 | 03.01.2020 00:00:00 |      0 | 1              |
| 12 | 31.12.2019 00:00:00 |   123 | 31.12.2019 00:00:00 | NULL                |      0 | 1              |
| 13 | 31.12.2019 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |      0 | 1              |
| 14 | 31.12.2019 00:00:00 |   125 | 01.01.2000 00:00:00 | 03.01.2020 00:00:00 |      0 | 1              |
| 15 | 30.12.2019 00:00:00 |   124 | 01.01.1995 00:00:00 | NULL                |    600 | NULL           |
| 16 | 30.12.2019 00:00:00 |   125 | 01.01.2000 00:00:00 | 03.01.2020 00:00:00 |      0 | 1              |
+----+---------------------+-------+---------------------+---------------------+--------+----------------+

rextester演示

g52tjvyc

g52tjvyc2#

你可以这样做:

WITH Dates AS (
            SELECT OpenDate From Stores WHERE Store=124 -- // this is the starting date
            UNION ALL 
            SELECT [GenGapDate] = DATEADD(DAY, 1, [GenGapDate])
            FROM Dates
            WHERE GenGapDate < (SELECT max(EndDate) From Stores WHERE store=124)
        ),

我不确定这是否是你要找的,因为你没有指定你的可变日期是从哪里来的。

相关问题