2017-12-13 133 views
13

Với cấu trúc bảng sau đây, là biểu diễn cho tuyến xe buýt nơi hành khách lên và xuống xe buýt với cảm biến cửa. Và, có một người ngồi trên xe buýt đó với một cái kẹp giữ một số điểm.Tính tải và tránh con trỏ

CREATE TABLE BusLoad(
ROUTE CHAR(4) NOT NULL, 
StopNumber INT NOT NULL, 
ONS INT, 
OFFS INT, 
SPOT_CHECK INT) 
go 
INSERT BusLoad VALUES('AAAA', 1, 5, 0, null) 
INSERT BusLoad VALUES('AAAA', 2, 0, 0, null) 
INSERT BusLoad VALUES('AAAA', 3, 2, 1, null) 
INSERT BusLoad VALUES('AAAA', 4, 6, 3, 8) 
INSERT BusLoad VALUES('AAAA', 5, 1, 0, null) 
INSERT BusLoad VALUES('AAAA', 6, 0, 1, 7) 
INSERT BusLoad VALUES('AAAA', 7, 0, 3, null) 

Tôi muốn thêm cột "LOAD" vào bảng này để tính toán tải tại mỗi điểm dừng.

tải = dừng Previous tải + dừng ONS hiện tại - offs hiện tại dừng nếu SPOT_CHECK là null, nếu không LOAD = SPOT_CHECK

Kết quả mong đợi:

ROUTE StopNumber ONS OFFS SPOT_CHECK LOAD 
AAAA 1   5 0  NULL  5 
AAAA 2   0 0  NULL  5 
AAAA 3   2 1  NULL  6 
AAAA 4   6 3  8   8 
AAAA 5   1 0  NULL  9 
AAAA 6   0 1  7   7 
AAAA 7   0 3  NULL  4 

tôi có thể làm điều này với một con trỏ, nhưng có cách nào để thực hiện nó bằng truy vấn không?

+4

Bạn cũng có thể đăng tập hợp kết quả mong đợi không? –

+0

Bạn đang sử dụng phiên bản SQL Server nào? –

+0

2008 hoặc mới hơn là tốt –

Trả lời

10

Bạn có thể sử dụng các truy vấn sau đây:

select ROUTE, StopNumber, ONS, OFFS, SPOT_CHECK, 
     COALESCE(SPOT_CHECK, ONS - OFFS) AS ld, 
     SUM(CASE WHEN SPOT_CHECK IS NULL THEN 0 ELSE 1 END) 
     OVER (PARTITION BY ROUTE ORDER BY StopNumber) AS grp 
from BusLoad 

để có được:

ROUTE StopNumber ONS OFFS SPOT_CHECK ld grp 
---------------------------------------------------- 
AAAA 1   5 0  NULL  5 0 
AAAA 2   0 0  NULL  0 0 
AAAA 3   2 1  NULL  1 0 
AAAA 4   6 3  8   8 1 
AAAA 5   1 0  NULL  1 1 
AAAA 6   0 1  7   7 2 
AAAA 7   0 3  NULL  -3 2 

Tất cả các bạn muốn n là ow tổng chạy của ld qua ROUTE, grp phân vùng dữ liệu:

;WITH CTE AS (
.... 
previous query here 
) 
select ROUTE, StopNumber, ONS, OFFS, SPOT_CHECK, grp, 
     sum(ld) over (PARTITION BY ROUTE, grp ORDER BY StopNumber) as load 
from cte 

Demo here

Lưu ý: Các truy vấn trên làm việc cho các phiên bản bắt đầu từ năm 2012. Nếu bạn muốn có một truy vấn cho 2008 bạn phải bằng cách nào đó mô phỏng sum() over (order by ...). Bạn có thể tìm thấy nhiều bài viết có liên quan ở đây trong SO.

+1

thực sự đẹp –

+0

Cảm ơn! Logic của bạn ở đây đã giúp tôi phát triển một giải pháp Python Pandas bình đẳng. Tuyệt vời! –

2

Bạn có thể sử dụng truy vấn đệ quy

with act_load as 
(
    select *, ons load 
    from busload 
    where stopnumber = 1 and route = 'AAAA' 
    union all 
    select b.*, case when b.spot_check is null then l.load + b.ons - b.offs 
       else b.spot_check 
       end load 
    from busload b 
    join act_load l on b.StopNumber = l.StopNumber + 1 and 
        b.route = l.route 
) 
select * 
from act_load 

dbfiddle demo

+1

Bah! Tôi đã đi đến chính xác giải pháp tương tự như thế này nhưng nó đã cho tôi 9 phút nữa. – Jamiec

+0

Câu trả lời hay, cảm ơn bạn! –

Các vấn đề liên quan