SQL Server:获取其数据开始或月末的记录

时间:2013-05-22 12:56:22

标签: sql-server

我有一张桌子:

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.

任何人都可以帮我查询吗?

4 个答案:

答案 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
;

See a Live Demo at SQL Fiddle