0

我有一张桌子:

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

4 回答 4

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)
于 2013-05-22T13:06:36.957 回答
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
;

在 SQL Fiddle 上查看现场演示

于 2013-05-22T17:05:28.427 回答
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,然后可以将其用于可能能够利用索引的连接中 - 如果存在索引.

以上确实有一个好处 - 很容易看到它在做什么。

于 2013-05-22T13:06:24.787 回答
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

此方法假设每个网站在每个日期在此表中只有一条记录

于 2013-05-22T13:12:03.620 回答