如何比较给定数据集的最新两个值
How to compare the latest two values for a given set of data
我需要一个查询,为每个在 MAX(PublishDate)上出版一本书的作者提供最新的作者、出版商和书籍,并比较每个作者最近 2 本书的出版商,看看它是否有变了。它不必是单个语句,但不能创建任何物理表。
declare @books TABLE(Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
INSERT INTO @books
VALUES ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11')
Output:
Author Publisher PublisherChanged Book
Author A Publisher A 1 Book 1
Author C Publisher E 0 Book 5
Author D Publisher F 0 Book 7
Author E Publisher G 1 Book 9
2008 R2
你必须在它自己上创建一个关系,我在这里使用 row_number()
基本上将 table 连接到它自己上。如果它很大 table,您可能想使用临时 table 而不是 cte。我将排名第 1 的发布者与排名第 2 的发布者进行比较:
declare @books table (Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
insert into @books
values ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11');
declare @max_date date = (
select max(PublishDate)
from @books
);
with EvaluateChanges (
Author
,PublishDate
,Publisher
,Title
,DateRanking
)
as (
select Author
,PublishDate
,Publisher
,Title
,row_number() over (partition by Author order by PublishDate desc)
from @books
)
select e1.Author
,e1.Publisher
,case when isnull(e2.Publisher, e1.Publisher) <> e1.Publisher then 1 else 0 end as PublisherChanged
,e1.Title
from EvaluateChanges as e1
left join EvaluateChanges as e2
on e1.Author = e2.Author
and e2.DateRanking = 2
where cast(e1.PublishDate as date) = @max_date
and e1.DateRanking = 1;
2012 年以后
这是 2012 年的解决方案。我使用 2012 年引入的 lead()
函数帮助这里分析作者的上一行。 isnull
的原因是当分区中没有要比较的前一行时,lead()
将 null
。当它是 null
时,我通过为当前行上下文分配与 Publisher
相同的值来告诉评估假设没有变化。我正在为您的最大日期使用日期变量 cast
因为您的字段是 datetime
.
declare @books table (Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
insert into @books
values ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11');
declare @max_date date = (
select max(PublishDate)
from @books
);
with EvaluateChanges (
Author
,PublishDate
,Publisher
,Title
,PublisherChanged
)
as (
select Author
,PublishDate
,Publisher
,Title
,case
when isnull(lead(Publisher) over (
partition by author order by PublishDate desc
), Publisher) <> Publisher
then 1
else 0
end
from @books
)
select Author
,Publisher
,PublisherChanged
,Title
from EvaluateChanges
where cast(PublishDate as date) = @max_date;
更多关于 lead()
及其堂兄 lag()
的阅读:
https://docs.microsoft.com/en-us/sql/t-sql/functions/lead-transact-sql?view=sql-server-2017
https://docs.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql?view=sql-server-2017
我需要一个查询,为每个在 MAX(PublishDate)上出版一本书的作者提供最新的作者、出版商和书籍,并比较每个作者最近 2 本书的出版商,看看它是否有变了。它不必是单个语句,但不能创建任何物理表。
declare @books TABLE(Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
INSERT INTO @books
VALUES ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11')
Output:
Author Publisher PublisherChanged Book
Author A Publisher A 1 Book 1
Author C Publisher E 0 Book 5
Author D Publisher F 0 Book 7
Author E Publisher G 1 Book 9
2008 R2
你必须在它自己上创建一个关系,我在这里使用 row_number()
基本上将 table 连接到它自己上。如果它很大 table,您可能想使用临时 table 而不是 cte。我将排名第 1 的发布者与排名第 2 的发布者进行比较:
declare @books table (Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
insert into @books
values ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11');
declare @max_date date = (
select max(PublishDate)
from @books
);
with EvaluateChanges (
Author
,PublishDate
,Publisher
,Title
,DateRanking
)
as (
select Author
,PublishDate
,Publisher
,Title
,row_number() over (partition by Author order by PublishDate desc)
from @books
)
select e1.Author
,e1.Publisher
,case when isnull(e2.Publisher, e1.Publisher) <> e1.Publisher then 1 else 0 end as PublisherChanged
,e1.Title
from EvaluateChanges as e1
left join EvaluateChanges as e2
on e1.Author = e2.Author
and e2.DateRanking = 2
where cast(e1.PublishDate as date) = @max_date
and e1.DateRanking = 1;
2012 年以后
这是 2012 年的解决方案。我使用 2012 年引入的 lead()
函数帮助这里分析作者的上一行。 isnull
的原因是当分区中没有要比较的前一行时,lead()
将 null
。当它是 null
时,我通过为当前行上下文分配与 Publisher
相同的值来告诉评估假设没有变化。我正在为您的最大日期使用日期变量 cast
因为您的字段是 datetime
.
declare @books table (Author nvarchar(30), PublishDate datetime2(3), Publisher nvarchar(30), Title nvarchar(30))
insert into @books
values ('Author A', '15 June 2017 15:47', 'Publisher A', 'Book 1'),
('Author A', '15 May 2016 14:47', 'Publisher B', 'Book 2'),
('Author B', '15 May 2016 14:47', 'Publisher C', 'Book 3'),
('Author B', '15 April 2015 13:47', 'Publisher D', 'Book 4'),
('Author C', '15 June 2017 15:47', 'Publisher E', 'Book 5'),
('Author C', '15 May 2014 14:47', 'Publisher E', 'Book 6'),
('Author D', '15 June 2017 15:47', 'Publisher F', 'Book 7'),
('Author D', '15 May 2013 14:47', 'Publisher F', 'Book 8'),
('Author E', '15 June 2017 15:47', 'Publisher G', 'Book 9'),
('Author E', '15 May 2012 14:47', 'Publisher H', 'Book 10'),
('Author E', '15 April 2011 13:47', 'Publisher I', 'Book 11');
declare @max_date date = (
select max(PublishDate)
from @books
);
with EvaluateChanges (
Author
,PublishDate
,Publisher
,Title
,PublisherChanged
)
as (
select Author
,PublishDate
,Publisher
,Title
,case
when isnull(lead(Publisher) over (
partition by author order by PublishDate desc
), Publisher) <> Publisher
then 1
else 0
end
from @books
)
select Author
,Publisher
,PublisherChanged
,Title
from EvaluateChanges
where cast(PublishDate as date) = @max_date;
更多关于 lead()
及其堂兄 lag()
的阅读:
https://docs.microsoft.com/en-us/sql/t-sql/functions/lead-transact-sql?view=sql-server-2017 https://docs.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql?view=sql-server-2017