2014-01-14 159 views
0

假設我有一個公共車庫應用程序,其中包含一個數據表,該數據表示可以在車庫,車庫外或店內進行維護。它看起來像這樣:獲取記錄狀態的SQL服務器2008的歷史

+-----------------------+-----+-----+ 
|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,但我覺得那個人過於寬容,並不像這個人一般。

+1

事端,如:'選擇日期,狀態,從表組COUNT(*)的日子(日期),state' – Melon

+0

即查詢錯過兩樣東西:它不會給我日期,當沒有巴士在哪裏改變狀態,並且沒有考慮在特定日子沒有改變狀態的巴士。再次查看所需的結果集。 – Fontanka16

+0

這只是一個提示。 (這是在這裏,而不是在答案) – Melon

回答

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)

+0

我想要的最終結果是這樣的表,但我試圖簡化問題的核心問題(在我的opinoin) 但你的答案錯過了一件事:我想有數量來總結屬於車庫的所有公共汽車的狀態。所以在九月的計數將是4,1不爲空,1 – Fontanka16

+0

@ Fontanka16:目前尚不清楚爲什麼4,1。但你也可以使用'[Total] = COUNT(*)OVER(PARTITION BY DATEADD(day,DATEDIFF(day,0,[Date]),0))'來計算每天所有輸入點的數量。或者相應地改變邏輯。如果你想包含'BusId',你甚至可以用多列進行分區。 –

+0

4,1因爲在狀態表1總線當天改變了狀態。結果是,4輛公共汽車出了,1輛在車庫裏 – Fontanka16

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]