Sql server 忽略日期范围内的行

Sql server 忽略日期范围内的行,sql-server,tsql,Sql Server,Tsql,我有以下数据: CREATE TABLE SampleData ( orderid int, [name] nvarchar(1), [date] date ); INSERT INTO SampleData VALUES (1, 'a', '2017-01-01'), (2, 'a', '2017-01-05'), (3, 'a', '2017-02-01'), (4, 'a', '2017-04-01'), (5, 'a', '2017-10-01'), (6, 'b

我有以下数据:

CREATE TABLE SampleData
(
    orderid int,
    [name] nvarchar(1),
    [date] date
);
INSERT INTO SampleData
VALUES
(1, 'a', '2017-01-01'),
(2, 'a', '2017-01-05'),
(3, 'a', '2017-02-01'),
(4, 'a', '2017-04-01'),
(5, 'a', '2017-10-01'),
(6, 'b', '2017-04-01');
我需要根据以下规则检索每个新订单:

名称的第一个日期是该名称的“当前订单” 名称相同但与“当前订单”相差不到3个月的订单视为同一订单,需要忽略 与“当前”订单3个月或以上的差异被视为新订单,现在需要比较SampleData orderid 1和4中的“当前订单”,而不是3和4,因为3不是当前订单 如果名称和日期相同,则orderid最低的行为上级 因此,对于示例数据,我需要以下结果:

id name, date
1  a     2017-01-01
4  a     2017-04-01
5  a     2017-10-01
6  b     2017-04-01

我尝试了几种方法,但没有成功。关于如何实现这一点,您有什么想法吗?

下面是一个快速修复解决方案,如果您的代码扩展到提供的示例数据之外,则可以在此基础上进行构建。我会事先声明,这不是最漂亮的解决方案,但它确实会返回您指定的结果集

如果有的话,你可能想考虑一下T-SQL窗口函数和解析函数。我会建议他们不能很好地处理所有的数据类型

我使用下面的解决方案的目标是对行进行排序,同时按名称和日期字段的顺序进行分区。因此,您有一些类似于订单id的内容,但排名是针对下订单的客户的

我会尽力回答任何问题:

if object_id('tempdb..#tmp_SampleData','u') is not null
    drop table #tmp_SampleData

CREATE TABLE #tmp_SampleData
(
    orderid int,
    [name] nvarchar(1),
    [date] date
);
INSERT INTO #tmp_SampleData
VALUES
(1, 'a', '2017-01-01'),
(2, 'a', '2017-01-05'),
(3, 'a', '2017-02-01'),
(4, 'a', '2017-04-01'),
(5, 'a', '2017-10-01'),
(6, 'b', '2017-04-01');

if object_id('tempdb..#tmp_iter','u') is not null
    drop table #tmp_iter 

select 
 orderid
,name
,date
,rank() over (partition by name order by date) [Rank] 
,lag(orderid,1,0) over (partition by name order by date) [LagRank]
--,rank() over (partition by name order by date desc) [ReverseRank]
into #tmp_Iter 
from #tmp_SampleData

if object_id('tempdb..#tmp_final','u') is not null
    drop table #tmp_final 


select 
 i.orderid
,i.name
,i.date
,datediff(month,i.date,i2.date) [MonthsPassed]
into #tmp_final 
from #tmp_Iter i
    left join #tmp_Iter i2 
        on i.Rank = i2.LagRank

select * 
from #tmp_final 
where 1=1
and MonthsPassed > 3 
or MonthsPassed = 0 
or MonthsPassed < 0 
or MonthsPassed is null 

@SQLUser44,感谢您的输入。不幸的是,您的代码不起作用。下表的结果应该是orderid的1、6、7、8和9。你的结果是1,2,3,5,6,7,8和9

INSERT INTO #tmp_SampleData
VALUES
(1,'a','2017-01-01'),
(2,'a','2017-01-08'),
(3,'a','2017-05-01'),
(4,'a','2017-01-05'),
(5,'a','2017-02-01'),
(6,'b','2017-01-01'),
(7,'b','2017-09-01'),
(8,'c','2017-10-01'),
(9,'a','2017-04-01');
我提出了以下有效的方法,但我认为它将缺乏性能

if object_id('tempdb..#tmp_SampleData','u') is not null
drop table #tmp_SampleData

CREATE TABLE #tmp_SampleData
(
    orderid int,
    [name] nvarchar(1),
    [date] date
);
INSERT INTO #tmp_SampleData
VALUES
(1,'a','2017-01-01'),
(2,'a','2017-01-08'),
(3,'a','2017-05-01'),
(4,'a','2017-01-05'),
(5,'a','2017-02-01'),
(6,'b','2017-01-01'),
(7,'b','2017-09-01'),
(8,'c','2017-10-01'),
(9,'a','2017-04-01');

DECLARE Test_Cursor CURSOR FOR  
SELECT * FROM #tmp_SampleData ORDER BY [name], [date];
OPEN Test_Cursor;

DECLARE @orderid int;
DECLARE @name nvarchar(255); 
DECLARE @date date; 

FETCH NEXT FROM Test_Cursor INTO @orderid, @name, @date;

DECLARE @current_date date = @date;
DECLARE @current_name nvarchar(255) = @name;
DECLARE @listOfIDs TABLE (orderid int);
INSERT @listOfIDs values(@orderid);

WHILE @@FETCH_STATUS = 0  
    BEGIN
       IF(@name = @current_name AND DATEDIFF(MONTH, @current_date, @date) >= 3)
          BEGIN
             SET @current_date = @date
             INSERT @listOfIDs values(@orderid)
          END
       IF(@name != @current_name)
          BEGIN
             SET @current_name = @name
             SET @current_date = @date
             INSERT @listOfIDs values(@orderid)
          END
    FETCH NEXT FROM Test_Cursor INTO @orderid, @name, @date; 
    END;  
CLOSE Test_Cursor;
DEALLOCATE Test_Cursor;
SELECT * FROM #tmp_SampleData WHERE orderid IN (SELECT orderid FROM @listOfIDs);

非常欢迎性能更好的替代方案

如果一个顺序重叠导致第二个和第三个bullet语句的结果为true,该怎么办?您的insert语句缺少orderidfield@scsimon,如果名称和日期相同,则orderid最低的行为上级order@maSTAShuFu锋利的我删除了身份,这就是为什么