HI您能帮我查询以下结果吗?我需要每个名称和每个日期的最近5天有效期。
输入
Name date Active
==== ==== ========
N1 07-30-2018 Y
N1 07-31-2018 N
N1 08-01-2018 Y
N1 08-02-2018 Y
输出
Name date date2 Active
==== ========== ======= ======
N1 07-30-2018 07-25-2018 Y
N1 07-30-2018 07-26-2018 Y
N1 07-30-2018 07-28-2018 Y
N1 07-30-2018 07-29-2018 Y
N1 07-30-2018 07-30-2018 Y
N1 08-01-2018 07-27-2018 Y
N1 08-01-2018 07-28-2018 Y
N1 08-01-2018 07-29-2018 Y
N1 08-01-2018 07-30-2018 Y
N1 08-01-2018 08-01-2018 Y
N1 08-02-2018 07-28-2018 Y
N1 08-02-2018 07-29-2018 Y
N1 08-02-2018 07-30-2018 Y
N1 08-02-2018 08-01-2018 Y
N1 08-02-2018 08-02-2018 Y
我正在使用以下查询来获取此输出,请您更正
DECLARE @windowStart DATETIME SET @windowStart = '2016-08-01 00:00:00'
DECLARE @windowEnd DATETIME SET @windowEnd = '2016-09-01 23:00:00';
Select a.Wellname,cast(a.timestamp as date) as date1,b.timestamp --,date2 = dateadd(DAY,-N,timestamp)
From TableA --where cast(timestamp as date)>=@windowStart and cast(timestamp as date)<= @windowEnd
Cross Join (
Select *
from (
Select distinct m.wellname, cast(m.[timestamp] as date) as timestamp ,Rank() Over ( partition by m.wellname order by timestamp desc) as Rank
from TableA m
where m.updown<>'D' and cast(m.[timestamp] as date) <= (Select cast(T.timestamp as date) from dbo.odr_nd_well_data T where cast(T.timestamp as date)=cast(a.timestamp as date)) and m.wellname in ('WN1','WN2')
group by m.wellname,m.timestamp
) a where a.rank<=5
) B
--on a.wellname=b.wellname
where a.wellname='WN1' and cast(a.timestamp as date)>=@windowStart and cast(a.timestamp as date)<= @windowEnd
Order by a.wellname,a.date1,cast(b.timestamp as date)
答案 0 :(得分:3)
也许一个CROSS JOIN
带有临时提示表
示例
Select A.*
,date2 = dateadd(DAY,-N,date)
From YourTable A
Cross Join (Select Top 5 N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1) B
Order By name,date,dateadd(DAY,-N,date)
返回
Name date date2
N1 2018-08-01 2018-07-27
N1 2018-08-01 2018-07-28
N1 2018-08-01 2018-07-29
N1 2018-08-01 2018-07-30
N1 2018-08-01 2018-07-31
N1 2018-08-02 2018-07-28
N1 2018-08-02 2018-07-29
N1 2018-08-02 2018-07-30
N1 2018-08-02 2018-07-31
N1 2018-08-02 2018-08-01
答案 1 :(得分:1)
Saw your second post was closed. Take a peek at
Example
;with cte as (
Select A.Name
,A.Date
,date2 = dateadd(DAY,-N,A.date)
,A.Active
,RN = Row_Number() over (Partition By A.Name,A.Date Order by dateadd(DAY,-N,A.date) desc)
From YourTable A
Cross Join (Select Top 10 N=-1+Row_Number() Over (Order By (Select NULL)) From master..spt_values n1) B
Left Join (Select * from YourTable Where Active='N') C on A.Name=C.Name and dateadd(DAY,-N,A.date)=C.date
Where A.Active='Y'
and C.Name is null
)
Select Name
,Date
,Date2
,Active
From cte
Where RN <=5
Order by Name,Date,Date2
Returns
Name Date Date2 Active
N1 2018-07-30 2018-07-26 Y -- I think you had a typo in the desired results
N1 2018-07-30 2018-07-27 Y
N1 2018-07-30 2018-07-28 Y
N1 2018-07-30 2018-07-29 Y
N1 2018-07-30 2018-07-30 Y
N1 2018-08-01 2018-07-27 Y
N1 2018-08-01 2018-07-28 Y
N1 2018-08-01 2018-07-29 Y
N1 2018-08-01 2018-07-30 Y
N1 2018-08-01 2018-08-01 Y
N1 2018-08-02 2018-07-28 Y
N1 2018-08-02 2018-07-29 Y
N1 2018-08-02 2018-07-30 Y
N1 2018-08-02 2018-08-01 Y
N1 2018-08-02 2018-08-02 Y
答案 2 :(得分:0)
基于另一个问题中的简化示例。这是获得结果的替代方法,而且可能更简单:
ID - ALIAS
1 - PIPPO
2 - PLUTO
这里我不清楚的是如何处理7/25到7/29之间的日期。这些日期出现在示例输出中,但没有出现在输入中。您是否要基于数字或日历表(假设它们会一直处于活动状态)生成这些日期,是否有更多未共享的输入数据,或者您想要更少的输出?假设存在更多未共享的输入,则写出此答案。
答案 3 :(得分:-1)
或者,您也可以将“过程方法”用作以下代码:
declare @tbPrevDates TABLE(
[name] char (3)
,[date] smalldatetime
,[date2] smalldatetime
)
declare @count int = -5
WHILE @count<>0
BEGIN
INSERT @tbPrevDates SELECT [name], [date], DateAdd(d, @count, [date]) FROM YourTable
SET @count=@Count+1
END
SELECT * from @tbPrevDates
ORDER BY
[name],[date],[date2]
但是,约翰·卡佩莱蒂(John Cappelletti)的答案相对于SQL SERVER更紧凑,更高级,我的答案有点“泛型”……