我有一张桌子:
ID Website Artticles_Count Date
---------------------------------------------
1 example.com 150 2012-05-1
2 example.com 190 2012-05-2
3 example.com 219 2012-05-3
.
.
.
30 example.com 4350 2012-05-30
31 example.com 4432 2012-05-31
32 example.com 4503 2012-06-1
我希望在很长一段时间(2 - 3年)内显示文章的历史记录。因为记录计数会很多,我想要显示一个夏季并检索每个月的开始和结束的Ariticles_Count值。在上面显示的示例表中,必须在2012年5月检索150和4432.
任何人都可以帮我查询吗?
答案 0 :(得分:3)
您可以使用row_number
为一个月内的每一行分配一个数字。然后,您可以对该月进行分组,并使用max(case ...
选择该月的第一个和最后一个条目:
select website
, year(date)
, month(date)
, max(case when rn_asc = 1 then Artticles_Count end) as FirstOfMonth
, max(case when rn_desc = 1 then Artticles_Count end) as LastOfMonth
from (
select row_number() over (
partition by year(date), month(date)
order by date) rn_asc
, row_number() over (
partition by year(date), month(date)
order by desc) rn_desc
, *
from Artticles
) as SubQueryAlias
group by
website
, year(date)
, month(date)
答案 1 :(得分:1)
你还没有说过你希望得到什么格式的结果。这是我的尝试:
declare @t table (ID int not null,Website varchar(20) not null, Artticles_Count int not null, Date date not null)
insert into @t(ID,Website,Artticles_Count,Date) values
(1 ,'example.com',150 , '20120501'),
(2 ,'example.com',190 , '20120502'),
(3 ,'example.com',219 , '20120503'),
(30,'example.com',4350, '20120530'),
(31,'example.com',4432, '20120531'),
(32,'example.com',4503, '20120601')
select Website,YEAR(Date),MONTH(Date),
MAX(CASE WHEN MONTH(DATEADD(day,-1,Date)) != MONTH(Date) THEN Artticles_Count END) as MonthStart,
MAX(CASE WHEN MONTH(DATEADD(day,1,Date)) != MONTH(Date) THEN Artticles_Count END) as MonthEnd
from @t
where MONTH(DATEADD(day,-1,Date)) != MONTH(Date) or
MONTH(DATEADD(day,1,Date)) != MONTH(Date)
group by Website,YEAR(Date),MONTH(Date)
产生:
Website MonthStart MonthEnd
-------------------- ----------- ----------- ----------- -----------
example.com 2012 5 150 4432
example.com 2012 6 4503 NULL
(我们没有6月数据的月末数据)
然而,上述情况可能并不顺利 - 您需要告诉我们它是否表现不佳。它不能很好地运行的原因是它排除了索引的使用。可以构建一个替代公式,我们使用合理的起始月份和数字表来生成包含所有月份开始/结束日期的CTE,然后可以在可能能够利用索引的联接中使用 - 如果存在
以上确实有一个好处 - 很容易看出它在做什么。
答案 2 :(得分:1)
这是你想要的吗?
select website, Date,
f.Artticles_Count FirstCount,
l.Artticles_Count LastCount
from your_table f
join yourtable l
On Day(f.Date) = 1
And l.Date = DateAdd(day, -1, DateAdd(Month, 1, f.date))
Where date Between @startDate And @EndDate
此方法假设此表中每个日期的每个网站只有一条记录
答案 3 :(得分:1)
这是另一个工作策略:
SELECT TOP 1 WITH TIES
*
FROM
dbo.Artticles A
ORDER BY
CASE WHEN Date IN (
Max(Date) OVER (PARTITION BY Year(Date), Month(Date)),
Min(Date) OVER (PARTITION BY Year(Date), Month(Date))
) THEN 0 ELSE 1 END
;