我有以下数据:
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');
我需要根据以下规则检索每个新订单:
因此,对于样本数据,我需要以下结果:
id name, date
1 a 2017-01-01
4 a 2017-04-01
5 a 2017-10-01
6 b 2017-04-01
我尝试了几种方法,但没有成功。关于如何实现这一目标的任何想法?
答案 0 :(得分:0)
以下是一个快速修复解决方案,如果您的代码超出所提供的示例数据,则可以构建该解决方案。我会事先声明这不是最漂亮的解决方案,但它确实会返回您所指示的结果集。
如果有的话,您可能需要考虑查看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
答案 1 :(得分:0)
@ 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);
非常欢迎表现更佳的替代品!