获取记录状态sql server 2008的历史记录

时间:2014-01-14 08:27:00

标签: sql sql-server sql-server-2008 tsql

假设我有一个Bus Garage应用程序,其中包含一个数据表,代表了车库,车库外或商店进行维护的公交车。它看起来像这样:

+-----------------------+-----+-----+
|Date                   |BusId|State|
+-----------------------+-----+-----+
|2013-09-12 15:02:41,844|1    |IN   |
+-----------------------+-----+-----+
|2013-09-12 15:02:41,844|2    |IN   |
+-----------------------+-----+-----+
|2013-09-12 15:02:41,844|3    |OUT  |
+-----------------------+-----+-----+
|2013-09-12 15:02:41,844|4    |OUT  |
+-----------------------+-----+-----+
|2013-09-12 15:02:41,844|5    |OUT  |
+-----------------------+-----+-----+
|2013-09-13 15:02:41,844|1    |OUT  |
+-----------------------+-----+-----+
|2013-09-14 15:02:41,844|1    |IN   |
+-----------------------+-----+-----+
|2013-09-15 15:02:41,844|1    |OUT  |
+-----------------------+-----+-----+
|2013-09-15 15:02:41,844|2    |OUT  |
+-----------------------+-----+-----+

现在我想制作一个漂亮的日常(或一小时等)数据集,让我概述车库里有多少辆公共汽车在哪里。

+-------------------+-----+------------+
|Date               |State|Count(buses)|
+-------------------+-----+------------+
|2013-09-12 16:00:00|IN   |2           |
+-------------------+-----+------------+
|2013-09-12 16:00:00|OUT  |3           |
+-------------------+-----+------------+ 
|2013-09-13 16:00:00|IN   |1           |
+-------------------+-----+------------+
|2013-09-13 16:00:00|OUT  |4           |
+-------------------+-----+------------+
|2013-09-14 16:00:00|IN   |2           |
+-------------------+-----+------------+
|2013-09-14 16:00:00|OUT  |3           |
+-------------------+-----+------------+
|2013-09-15 16:00:00|IN   |0           |
+-------------------+-----+------------+
|2013-09-15 16:00:00|OUT  |5           |
+-------------------+-----+------------+

如何(在代码中没有必要解释)我会使用TSQL来做这个吗? 我有一个要求,那就是我不能在我的陈述中使用变量声明,因为我将它作为一个视图。

我问了一个非常similar question,但我觉得那个人过于夸张而不像这个那么笼统。

2 个答案:

答案 0 :(得分:2)

你真的想要每天每小时多条记录来显示不同的状态吗?我会让他们成为专栏。您可以使用CTE和OVER子句来计算每天/每小时组:

WITH CTE AS 
(
    SELECT [Date] = DATEADD(day, DATEDIFF(day, 0, [Date]),0), 
           [BusId], [State],
           [IN]  = SUM(CASE WHEN State='IN'  THEN 1 END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, [Date]),0)),
           [Out] = SUM(CASE WHEN State='Out' THEN 1 END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, [Date]),0)),
           [DayNum] = ROW_NUMBER() OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, [Date]),0)
                                         ORDER BY [Date], [BusID], [State])
    FROM dbo.Garage g    
)
SELECT [Date], [BusId], [State], [IN], [OUT]
FROM CTE 
WHERE [DayNum] = 1

Demo

结果:

DATE                               BUSID   STATE   IN   OUT
September, 12 2013 00:00:00+0000    1       IN     2    3
September, 13 2013 00:00:00+0000    1       OUT  (null) 1
September, 14 2013 00:00:00+0000    1       IN     1    (null)
September, 15 2013 00:00:00+0000    1       OUT  (null) 2

即使在SQL-Server 2005中也是如此。如果您想按小时而不是按天分组,则必须在任何地方将DATEADD(day, DATEDIFF(day, 0, [Date]),0)更改为DATEADD(hour, DATEDIFF(hour, 0, [Date]),0)

答案 1 :(得分:0)

试试这个......

DECLARE @businfo AS TABLE([date] datetime,busid int,[state] varchar(5))

INSERT INTO @businfo VALUES('2013-09-12 15:02:41',1,'IN')
INSERT INTO @businfo VALUES('2013-09-12 15:02:41',2,'IN')
INSERT INTO @businfo VALUES('2013-09-12 15:02:41',3,'OUT')
INSERT INTO @businfo VALUES('2013-09-12 15:02:41',4,'OUT')
INSERT INTO @businfo VALUES('2013-09-12 15:02:41',5,'OUT')
INSERT INTO @businfo VALUES('2013-09-13 15:02:41',1,'OUT')
INSERT INTO @businfo VALUES('2013-09-14 15:02:41',1,'IN')
INSERT INTO @businfo VALUES('2013-09-15 15:02:41',1,'OUT')
INSERT INTO @businfo VALUES('2013-09-15 15:02:41',2,'OUT')


select [date],[state],COUNT(busid) as [count(buses)] from @businfo
group by [date],[state]
order by [date]