Sql 从每个名称的当前日期中获取最后5个日期
嗨,你能帮我查询一下下面的内容吗。我需要每个姓名和日期的最后5个活动日 输入 输出Sql 从每个名称的当前日期中获取最后5个日期,sql,sql-server,Sql,Sql Server,嗨,你能帮我查询一下下面的内容吗。我需要每个姓名和日期的最后5个活动日 输入 输出 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-
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)
DECLARE@windowStart DATETIME SET@windowStart='2016-08-01 00:00:00'
声明@windowEnd日期时间集@windowEnd='2016-09-01 23:00:00';
选择a.Wellname,cast(a.timestamp作为日期)作为date1,b.timestamp--,date2=dateadd(DAY,-N,timestamp)
从TableA--where cast(timestamp as date)>=@windowStart和cast(timestamp as date)可能是一个带有特殊计数表的交叉连接
示例
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)
;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
返回
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
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
作为替代方案,您也可以使用“程序方法”作为以下代码:
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]
declare@tbPrevDates表(
[姓名]字符(3)
,[date]smalldatetime
,[date2]smalldatetime
)
声明@countint=-5
而@count0
开始
插入@tbPrevDates从您的表中选择[name]、[date]、DateAdd(d、@count、[date])
设置@count=@count+1
终止
从@tbPrevDates中选择*
订购人
[姓名],[日期],[日期2]
但是,John Cappelletti的答案对于SQL SERVER来说更加简洁和高级,我的答案有点“通用”…基于另一个问题中的简化示例。这是实现结果的另一种方法,可以说更简单:
select t1.name, t1.date, t2.date date2, t1.active
from (
select distinct name, date from [table] where active = 'Y'
) t1
cross apply (
select top 5 date
from [table]
where active = 'Y' and name = t1.name and date <= t1.date
order by date desc
) t2
order by name, date, date2
选择t1.name、t1.date、t2.date-date2、t1.active
从(
从[table]中选择不同的名称和日期,其中active='Y'
)t1
交叉应用(
选择前5个日期
从[表]
其中active='Y'和name=t1.name和date看到你的第二篇帖子被关闭了
示例
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)
;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
你好,诺迪,谢谢你回复我。我需要在已经存在的过程中包含代码。什么使日期成为活动日期?@Richard我需要每天和每个姓名的最后5个活动日期,我不需要过去5天内不活动的日期。这5个日期是活动日期,可以是最近5个日期中的任何一个。输入中没有7/25的任何数据大概是7月29日,但您将其包含在输出中。您是想生成这些日期,还是有更多的输入数据我们看不到?