SQL Server-显示列表中的前几项

SQL Server-显示列表中的前几项,sql,sql-server,Sql,Sql Server,我必须按小时对某人从特定国家打电话的次数进行排序。国家名单每月都会增加,因此,例如,我们可以添加巴西。我正在使用SQL Server 数据如下所示 2012-04-02 08:00:59 United States 2012-04-02 08:12:02 United States 2012-04-02 08:13:42 Canada 2012-04-02 08:13:56 United States 2012-04-02 08:14:07 Mexico 2012-

我必须按小时对某人从特定国家打电话的次数进行排序。国家名单每月都会增加,因此,例如,我们可以添加巴西。我正在使用SQL Server

数据如下所示

2012-04-02 08:00:59    United States
2012-04-02 08:12:02    United States
2012-04-02 08:13:42    Canada
2012-04-02 08:13:56    United States
2012-04-02 08:14:07    Mexico
2012-04-02 08:18:09    Canada
2012-04-02 08:19:50    United States
2012-04-02 08:34:34    Mexico
etc.
我想按小时列出前两个国家的数据

我希望它显示为:

Date                   Country          Calls
2012-04-02 08:00:00    United States    24
2012-04-02 08:00:00    Canada           19
--hidden--
2012-04-02 08:00:00    Mexico           12
我尝试的代码无效:

Declare @StartDate datetime, @EndDate datetime
    set @StartDate = '20120401 00:00:00'
  set @EndDate = '20120430 23:59:59'
SELECT  DATEADD(HOUR, DATEPART(HOUR, [date]), DATEDIFF(DAY, 0, [date])) as [date],
(SELECT COUNT([country]) FROM [mytable] WHERE [date] between @StartDate and @EndDate and [country] = 'United States' ) as [United_States]
,(SELECT COUNT([country]) FROM [mytable] WHERE [date] between @StartDate and @EndDate and [country] = 'Canada' ) as [Canada]
,(SELECT COUNT([country]) FROM [mytable] WHERE [date] between @StartDate and @EndDate and [country] = 'Mexico' ) as [Canada]
FROM [mytable] 
WHERE [date] between @StartDate and @EndDate
GROUP BY DATEADD(HOUR, DATEPART(HOUR, [date]), DATEDIFF(DAY, 0, [date]))
ORDER BY [date]

谢谢。

我认为最简单的解决方案是分两步进行

首先,必须将日期时间转换为偶数小时。通过将数据从一个表复制到另一个表,或通过视图,或向表中添加计算字段来实现

然后你做一些类似的事情

select date time, country, count(*) calls
from mytable
group by date, country

我不确定是不是count*-有人请纠正我。

试试这个。也许有一些语法错误,但我认为它的方向是正确的

SELECT T1.Date, T1.Country, SUM(1)
FROM CallsTable T1
GROUP BY DATEADD(hh, DATEDIFF(hh,0,T1.Date),0), T1.Country
HAVING T1.Country IN (SELECT TOP 2 T2.Country
                      FROM CallsTable T2
                      WHERE DATEADD(hh, DATEDIFF(hh,0,T2.Date),0) = DATEADD(hh, DATEDIFF(hh,0,T1.Date),0)
                      GROUP BY T2.Country
                      ORDER BY SUM(1) DESC                    
                      )
说明:

DATEADDhh,DATEDIFFhh,0,T1.Date,0截断分和秒,以便按小时分组

主要小组按小时和国家选择。内部选择是一个过滤器,因此只有两个顶部
将显示指定小时的呼叫国家。

添加到Darren Davies应答中,您可以进一步定义要按日期和小时解析的表输出:

SELECT 
  DATEADD(dd, 0, DATEDIFF(dd, 0, [Date])) as Date, 
  DATEPART(HOUR, [Date]) as Hour, 
  Country, 
  SUM(Calls)
FROM YourTable
GROUP BY 
  DATEADD(dd, 0, DATEDIFF(dd, 0, [Date])),
  DATEPART(HOUR, [Date]), 
  Country
未经测试:

SELECT date(yourdate) as mday, 
       datepart(hour, yourdate) as Yourhour, 
       country, 
       count(*) as calls, 
       ROW_NUMBER() OVER(PARTITION BY date(YourDate) & "-" & Datepart(hour,YourDate) & ORDER BY count(*) DESC) myCount
FROM yourTableName
GROUP BY date(yourdate), datepart(hour, yourdate)
having myCount <3
Order by count(*), mday, yourhour
不知怎的,在分区上的行数是。。。看起来它会让你得到你想要的,但我不能测试它。看看它的用途和为什么我认为它是你的目标

本质上,您希望在一天和一小时内创建不同的分区,按该分区集中的调用计数排序,并为每个记录/计数分配一个从1开始递增1的数字。然后,您希望将记录/计数限制在每天/小时分组的前2位。

使用and子句,这样比较容易阅读:

WITH CTE AS(
      SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, Date), 0)AS DateHour
    , Country
    , Count(*) OVER(Partition By Country, DATEPART(HOUR, Date))as GrpCount
    FROM @mytable
    WHERE date between @StartDate and @EndDate
)
SELECT DateHour AS Date, Country, GrpCount AS Calls
FROM CTE
GROUP BY Country, DateHour, GrpCount
ORDER BY DateHour
以下是您的示例数据:

declare @myTable table(date datetime, country varchar(20));
insert into @myTable values(convert(datetime,'2012-04-02 08:00:59',102),'United States');
insert into @myTable values(convert(datetime,'2012-04-02 08:13:42',102),'Canada');
insert into @myTable values(convert(datetime,'2012-04-02 08:13:56',102),'United States');
insert into @myTable values(convert(datetime,'2012-04-02 08:14:07',102),'Mexico');
insert into @myTable values(convert(datetime,'2012-04-02 08:18:09',102),'Canada');
insert into @myTable values(convert(datetime,'2012-04-02 08:19:50',102),'United States');
insert into @myTable values(convert(datetime,'2012-04-02 08:34:34',102),'Mexico');

Declare @StartDate datetime, @EndDate datetime;
    set @StartDate = '20120401 00:00:00';
    set @EndDate = '20120430 23:59:59';
结果:

Date                      Country           Calls
2012-04-02 08:00:00.000   Canada            2
2012-04-02 08:00:00.000   Mexico            2
2012-04-02 08:00:00.000   United States     3
这应该做到:

Declare @StartDate datetime, 
    @EndDate datetime
    set @StartDate = '20120401 00:00:00'
    set @EndDate = '20120430 23:59:59'

;WITH
  mytablePlusHours As
(
    SELECT *,
        DATEADD(HOUR, DATEPART(HOUR, [date]), DATEDIFF(DAY, 0, [date]))     AS [dateHour]
    FROM    [mytable]    
)
, mytableHourGroups As
(
    SELECT  dateHour, 
            country,
            COUNT(*)        As [countryCount],
            ROW_NUMBER() OVER(PARTITION BY dateHour ORDER BY countryCount) 
                            As [countryRank]
    FROM        mytablePlusHours
    GROUP BY    dateHour, country
)
SELECT  
        dateHour     AS [date],
        country,
        countryCount
FROM    mytableHourGroups
WHERE   [date] between @StartDate and @EndDate
  AND   countryRank <= 2
ORDER BY [date], countryRank

如何计算通话次数?通话次数只是为了举例说明我想如何排序,我还没有一个公式来确定您在这段时间内需要从每个国家拨打的电话的确切数量?每天?每小时?每个月?领带应该怎么办?那么如果美国有24个,加拿大有24个,那就是那一小时的前2名?或者如果美国有24个加拿大有19个墨西哥有19个应该怎么办?