2009-12-12 2 views
2

시나리오가 있는데 쿼리 방법을 잘 모릅니다. 샘플로서, 나는 테이블 구조를 다음과 버스 액션의 역사를 얻으려면 한 :

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

I :

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

내가 좋아하는 버스의 상태를 얻을 수있는 쿼리를 작성하려면 SQL Server 2008을 사용하고 있습니다.

도움 주셔서 감사합니다.테이블에서 기간 및 세부 정보를 묻는 쿼리

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

답변

-1

열 유형 등에 대한 특정 가정을 만들기 여기에는 기간이 포함되지 않습니다. 데이터를 주문할 때까지 이전 항목이 무엇인지 알 수 없습니다. 데이터가 정렬되면 연속 레코드의 시간 차이로 기간을 계산할 수 있습니다. 새 테이블을 선택한 다음 두 번째 쿼리를 실행하면됩니다.

BUSID로 그룹화하면 모든 버스에 대한 보고서가 제공됩니다.

+0

DURATION을 계산해야하므로이 기능은 작동하지 않습니다. – sajoz

+1

. 나는 바보 야. 죄송합니다. – kem

0

나는 순간 SQL 서버에 액세스 할 수없는, 그래서 다음에 구문 오류가있을 수 있습니다 :

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 

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/시퀀스가 ​​값을 잃는 경우가 종종 있습니다. 당신은 최고/제한 검색어를해야 할거야 어디에 ID>? 다음 기록을 얻기 위해서. – pstanton

+0

@pstanton : 예, 필요할 수 있습니다. 나는 위의 예제가 실용적인 응용을 위해 조정될 필요가 있다고 확신한다. –

1

:

또한 공통 테이블 식을 사용하는 방법에 대한 다음과 같은 외부 링크를 확인 할 수 있습니다 데이터를 비정규 화하여 시작할 수 있습니다. 한 행에 _time 및 end_time이 있습니다. 이렇게하면 쿼리가 훨씬 더 효율적입니다.

관련 문제