2009-12-12 32 views
2

我有一個場景,不太清楚如何查詢它。作爲一個樣本,我有以下表結構,並希望得到行動的歷史總線:

ID-----TIME---------BUSID----OPID----MOVING----STOPPED----PARKED----COUNT
1------10:10:10-----101------1101-----1---------0----------0---------15
2------10:10:11-----102------1102-----0---------1----------0---------5
3------10:11:10-----101------1101-----1---------0----------0---------15
4------10:12:10-----101------1101-----0---------1----------0---------15
5------10:13:10-----101------1101-----1---------0----------0---------19
6------10:14:10-----101------1101-----1---------0----------0---------19
7------10:15:10-----101------1101-----0---------1----------0---------19
8------10:16:10-----101------1101-----0---------0----------1---------0
9------10:17:10-----101------1101-----0---------0----------1---------0

我想編寫一個查詢得到總線喜歡的狀態:

BUSID----OPID----STATUS-----TIME---------DURATION---COUNT
101------1101----MOVING-----10:10:10-----2-----------15
101------1101----STOPPED----10:12:10-----1-----------15
101------1101----MOVING-----10:13:10-----2-----------19
101------1101----STOPPED----10:15:10-----1-----------19
101------1101----PARKED-----10:16:10-----2-----------0

我我正在使用SQL Server 2008.

感謝您的幫助。查詢以獲得表格的持續時間和詳細信息

回答

-1

製作有關列式等一些假設:

SELECT 
    BUSID, 
    OPID, 
    STATUS, 
    TIME, 
    DURATION, 
    COUNT 
FROM 
    TABLENAME 
WHERE 
    BUSID = 1O1 
ORDER BY 
    TIME 
; 
+0

由於需要計算DURATION,因此這不起作用。 – sajoz 2009-12-12 01:29:53

+1

沒錯。我是個白癡。抱歉。 – kem 2009-12-12 01:51:29

0

我沒有在時刻訪問SQL Server,所以有可能在以下語法錯誤:

SELECT 
    BUSID, 
    OPID, 
    IF (MOVING = 1) 'MOVING' ELSE IF (STOPPED = 1) 'STOPPED' ELSE 'PARKED' AS STATUS 
    TIME, 
    COUNT 
FROM BUS_DATA_TABLE 
GROUP BY BUSID 
ORDER BY TIME 

你會注意到這不包括持續時間。在您訂購數據之前,您不知道以前的條目是哪一個。一旦數據被排序,您可以計算持續時間,作爲連續記錄中的時間差。你可以通過選擇一個新表然後運行第二個查詢來完成。

BUSID分組,應該給你所有公交車的報告。

2

您可以使用Common Table Expressions來計算不同行之間的持續時間。

WITH cte_log AS 
(
    SELECT 
     Row_Number() 
    OVER 
    (
     ORDER BY time DESC 
    ) 
    AS 
     id, time, busid, opid, moving, stopped, parked, count 
    FROM 
     log_table 
    WHERE 
     busid = 101 
) 
SELECT 
    current_rows.busid, 
    current_rows.opid, 
    current_rows.time, 
    DATEDIFF(second, current_rows.time, previous_rows.time) AS duration 
    current_rows.count 
FROM 
    cte_log_position AS current_rows 
LEFT OUTER JOIN 
    log_table AS previous_rows ON ((current_rows.row_id + 1) = previous_rows.row_id) 
WHERE 
    current_rows.busid = 101 
ORDER BY 
    current_rows.time DESC; 

WITH的語句創建一個這個查詢的執行範圍內定義的臨時結果集。我們使用它來獲取每行的以前記錄,並計算當前記錄和前一記錄之間的時間差。

這個例子沒有經過測試,它可能無法正常工作,但我希望它能讓你朝着正確的方向前進。隨時留下反饋。

您可能還需要檢查有關如何使用公用表表達式以下外部鏈接:

+0

例如,如果一條記錄已被刪除,一個問題通常是id/sequences錯過一個值。你需要做一個頂部/限制查詢,其中id>?以獲得下一個記錄。 – pstanton 2009-12-12 01:42:20

+0

@ pstanton:是的,這可能是必要的。我確信上面的例子需要調整以適合實際應用。 – 2009-12-12 01:46:30

1

我個人使數據非規範化,以便開始_time和end_time在一行中。這將使查詢效率更高。