按sql

时间:2017-08-29 09:07:43

标签: sql-server

我有一张表格如下

order no        orderdate
01              2012-08-01 00:00
02              2012-08-01 00:10
03              2012-08-01 00:15
04              2012-08-01 00:30
05              2012-08-01 10:00
06              2012-08-01 10:35
07              2012-08-01 14:00
08              2012-08-02 20:30
09              2012-08-02 20:35
10              2012-08-02 23:00

我想按时间间隔对这些值进行分组(如00 -01,01-02 ...... 22- 23,23-24)(不包括日期值)

如何编写查询以按时间对此进行分组?

我希望获得24行(24个间隔)的订单数量

4 个答案:

答案 0 :(得分:1)

您可以使用 GROUP BY DATEPART(HOUR, orderdate)

查询:

SELECT DATEPART(HOUR, orderdate) AS HOUR,
       COUNT(*)                  AS ORDERS_PER_HOUR
FROM  YourTable
WHERE CAST(orderdate AS DATE) = @someDate
GROUP BY DATEPART(HOUR, orderdate)

请注意,如果orderdate中不存在每小时,则上述查询的结果将少于24个。

如果需要表示所有小时数,那么您可以使用递归公用表表达式(CTE)来首先生成所有小时数(0-23),并且然后离开你的桌子与CTE:

;WITH hours AS
(
    SELECT 0 AS h
    UNION ALL
    SELECT h + 1 FROM hours WHERE h < 23
)
SELECT hours.h AS HOUR,
       COUNT(YourTable.[order no]) AS ORDERS_PER_HOUR
FROM      hours
LEFT JOIN YourTable ON DATEPART(HOUR, orderdate) = hours.h
WHERE CAST(orderdate AS DATE) = @someDate
GROUP BY hours.h

答案 1 :(得分:0)

这是一个简单的解决方案,在这里您可以了解当天的小时......

drop table if exists dbo.tOrders;

create table dbo.tOrders (
    OrderNo varchar(50)
    , OrderDate datetime
);

insert into dbo.tOrders (OrderNo, OrderDate)
values ('01', '2012-08-01 00:00')
    , ('02', '2012-08-01 00:10')
, ('03',              '2012-08-01 00:15')
, ('04',              '2012-08-01 00:30')
, ('05',              '2012-08-01 10:00')
, ('06',              '2012-08-01 10:35')
, ('07',              '2012-08-01 14:00')
, ('08',              '2012-08-02 20:30')
, ('09',              '2012-08-02 20:35')
, ('10',              '2012-08-02 23:00')



select
    case
        when datepart(hour, t.OrderDate) >= 0 and datepart(hour, t.OrderDate) < 1 then '00-01'
        when datepart(hour, t.OrderDate) >= 1 and datepart(hour, t.OrderDate) < 2 then '01-02'
        when datepart(hour, t.OrderDate) >= 2 and datepart(hour, t.OrderDate) < 3 then '02-03'
        when datepart(hour, t.OrderDate) >= 3 and datepart(hour, t.OrderDate) < 4 then '03-04'
        when datepart(hour, t.OrderDate) >= 4 and datepart(hour, t.OrderDate) < 5 then '04-05'
        when datepart(hour, t.OrderDate) >= 5 and datepart(hour, t.OrderDate) < 6 then '05-06'
        when datepart(hour, t.OrderDate) >= 6 and datepart(hour, t.OrderDate) < 7 then '06-07'
        when datepart(hour, t.OrderDate) >= 7 and datepart(hour, t.OrderDate) < 8 then '07-08'
        when datepart(hour, t.OrderDate) >= 8 and datepart(hour, t.OrderDate) < 9 then '08-09'
        when datepart(hour, t.OrderDate) >= 9 and datepart(hour, t.OrderDate) < 10 then '09-10'
        when datepart(hour, t.OrderDate) >= 10 and datepart(hour, t.OrderDate) < 11 then '10-11'
        when datepart(hour, t.OrderDate) >= 11 and datepart(hour, t.OrderDate) < 12 then '11-12'
        when datepart(hour, t.OrderDate) >= 12 and datepart(hour, t.OrderDate) < 13 then '12-13'
        when datepart(hour, t.OrderDate) >= 13 and datepart(hour, t.OrderDate) < 14 then '13-14'
        when datepart(hour, t.OrderDate) >= 14 and datepart(hour, t.OrderDate) < 15 then '14-15'
        when datepart(hour, t.OrderDate) >= 15 and datepart(hour, t.OrderDate) < 16 then '15-16'
        when datepart(hour, t.OrderDate) >= 16 and datepart(hour, t.OrderDate) < 17 then '16-17'
        when datepart(hour, t.OrderDate) >= 17 and datepart(hour, t.OrderDate) < 18 then '17-18'
        when datepart(hour, t.OrderDate) >= 18 and datepart(hour, t.OrderDate) < 19 then '18-19'
        when datepart(hour, t.OrderDate) >= 19 and datepart(hour, t.OrderDate) < 20 then '19-20'
        when datepart(hour, t.OrderDate) >= 20 and datepart(hour, t.OrderDate) < 21 then '20-21'
        when datepart(hour, t.OrderDate) >= 21 and datepart(hour, t.OrderDate) < 22 then '21-22'
        when datepart(hour, t.OrderDate) >= 22 and datepart(hour, t.OrderDate) < 23 then '22-23'
        when datepart(hour, t.OrderDate) >= 23 then '23-00'
    end as TimeOfDay
    , count(t.OrderNo) as OrderCount
from dbo.tOrders t
group by
    case
        when datepart(hour, t.OrderDate) >= 0 and datepart(hour, t.OrderDate) < 1 then '00-01'
        when datepart(hour, t.OrderDate) >= 1 and datepart(hour, t.OrderDate) < 2 then '01-02'
        when datepart(hour, t.OrderDate) >= 2 and datepart(hour, t.OrderDate) < 3 then '02-03'
        when datepart(hour, t.OrderDate) >= 3 and datepart(hour, t.OrderDate) < 4 then '03-04'
        when datepart(hour, t.OrderDate) >= 4 and datepart(hour, t.OrderDate) < 5 then '04-05'
        when datepart(hour, t.OrderDate) >= 5 and datepart(hour, t.OrderDate) < 6 then '05-06'
        when datepart(hour, t.OrderDate) >= 6 and datepart(hour, t.OrderDate) < 7 then '06-07'
        when datepart(hour, t.OrderDate) >= 7 and datepart(hour, t.OrderDate) < 8 then '07-08'
        when datepart(hour, t.OrderDate) >= 8 and datepart(hour, t.OrderDate) < 9 then '08-09'
        when datepart(hour, t.OrderDate) >= 9 and datepart(hour, t.OrderDate) < 10 then '09-10'
        when datepart(hour, t.OrderDate) >= 10 and datepart(hour, t.OrderDate) < 11 then '10-11'
        when datepart(hour, t.OrderDate) >= 11 and datepart(hour, t.OrderDate) < 12 then '11-12'
        when datepart(hour, t.OrderDate) >= 12 and datepart(hour, t.OrderDate) < 13 then '12-13'
        when datepart(hour, t.OrderDate) >= 13 and datepart(hour, t.OrderDate) < 14 then '13-14'
        when datepart(hour, t.OrderDate) >= 14 and datepart(hour, t.OrderDate) < 15 then '14-15'
        when datepart(hour, t.OrderDate) >= 15 and datepart(hour, t.OrderDate) < 16 then '15-16'
        when datepart(hour, t.OrderDate) >= 16 and datepart(hour, t.OrderDate) < 17 then '16-17'
        when datepart(hour, t.OrderDate) >= 17 and datepart(hour, t.OrderDate) < 18 then '17-18'
        when datepart(hour, t.OrderDate) >= 18 and datepart(hour, t.OrderDate) < 19 then '18-19'
        when datepart(hour, t.OrderDate) >= 19 and datepart(hour, t.OrderDate) < 20 then '19-20'
        when datepart(hour, t.OrderDate) >= 20 and datepart(hour, t.OrderDate) < 21 then '20-21'
        when datepart(hour, t.OrderDate) >= 21 and datepart(hour, t.OrderDate) < 22 then '21-22'
        when datepart(hour, t.OrderDate) >= 22 and datepart(hour, t.OrderDate) < 23 then '22-23'
        when datepart(hour, t.OrderDate) >= 23 then '23-00'
    end

答案 2 :(得分:0)

我认为您可以使用此查询。正如您所看到的,要使用的主函数是wifi(参见https://docs.microsoft.com/en-us/sql/t-sql/functions/datepart-transact-sql),其中&#34;返回一个整数,表示指定日期的指定日期部分&#34;。

然后你可以使用GROUP BY来记录每小时的记录。

最后,您可以安排&#34;输出格式&#34;。

this.http.get(...)
   .retryWhen(error => error.delay(2000)) // if an error happens, wait 2 secs and try again
   .timeout(6000) // no success after 3 retries (6 secs), throw a timeout-error
   .map((res: Response) => res.json()) // everything went fine
   .catch(yourErrorFunction()) // do something with the error
   .subscribe()

或者如果您愿意:

DATE_PART(<format>, <date column>)

示例数据:

 SELECT CAST(X AS VARCHAR(2)) +'-'+CAST(X+1 AS VARCHAR(2)) AS HOUR_GROUP, COUNT(*) AS RC
FROM
 (SELECT  DATEPART(hh,ORD_DATE) X FROM ORD)A
 GROUP BY X
 ;

输出

 SELECT CAST(DATEPART(hh,ORD_DATE)  AS VARCHAR(2)) +'-'+CAST(DATEPART(hh,ORD_DATE) +1 AS VARCHAR(2)) AS HOUR_GROUP, COUNT(*) AS RC
 FROM ORD
 GROUP BY  DATEPART(hh,ORD_DATE)
 ;

如果您希望所有24小时组都可以使用:

INSERT INTO ORD VALUES (1,'2012-01-08 00:00');
INSERT INTO ORD VALUES (2,'2012-01-08 00:10');
INSERT INTO ORD VALUES (3,'2012-01-08 00:15');
INSERT INTO ORD VALUES (4,'2012-01-08 00:30');
INSERT INTO ORD VALUES (9,'2012-01-08 01:30');
INSERT INTO ORD VALUES (5,'2012-01-08 10:00');
INSERT INTO ORD VALUES(7,'2012-01-08 15:00');
INSERT INTO ORD VALUES (8,'2012-02-08 20:30');

输出:

HOUR_GROUP  RC
0-1     4
1-2     1
10-11   1
15-16   1
20-21   1

答案 3 :(得分:0)

如果我理解正确的话,无论日期如何,您都在寻找小时计数,即您正在寻找一天中最忙碌的时间?在这种情况下,您可以使用以下内容:

declare @hours table
(
hourpart datetime
)
INSERT INTO @hours VALUES
('00:00:00'),
('01:00:00'),
('02:00:00'),
('03:00:00'),
('04:00:00'),
('05:00:00'),
('06:00:00'),
('07:00:00'),
('08:00:00'),
('09:00:00'),
('10:00:00'),
('11:00:00'),
('12:00:00'),
('13:00:00'),
('14:00:00'),
('15:00:00'),
('16:00:00'),
('17:00:00'),
('18:00:00'),
('19:00:00'),
('20:00:00'),
('21:00:00'),
('22:00:00'),
('23:00:00')

declare @orders table
(
orderNo int,
orderDate datetime)


INSERT INTO @orders VALUES
(01,'2012-08-01 00:00'),
(02,'2012-08-01 00:10'),
(03,'2012-08-01 00:15'),
(04,'2012-08-01 00:30'),
(05,'2012-08-01 10:00'),
(06,'2012-08-01 10:35'),
(07,'2012-08-01 14:00'),
(08,'2012-08-02 20:30'),
(09,'2012-08-02 20:35'),
(10,'2012-08-02 23:00'),
(11,'2012-08-01 20:25')

SELECT convert(varchar(8), h.hourpart, 108), COUNT(*) FROM @orders o 
INNER JOIN @hours h
ON DATEPART(hour, o.orderdate) = DATEPART(hour, h.hourpart)
GROUP BY h.hourpart
ORDER BY h.hourpart

结果:

00:00:00    4
10:00:00    2
14:00:00    1
20:00:00    3
23:00:00    1