TSQL Order BY on occasion doesn't order correctly

杀马特。学长 韩版系。学妹 提交于 2019-12-25 19:38:04

问题


TSQL MSSQL 2008r2

I'm re-writing the question to try and make it clear what the issue is that I'm trying to explain.

I've got a stored proc that takes 3 parameters. VehicleKey, StartDate and EndDateTime. I'm querying a Data Warehouse db. So the data shouldn't change.

When the proc is called with the same parameters then most of the time the results will be as expected but on some random occasions, with those same parameters, the results differ. I'm querying a Data WH so the data doesn't change.

The problem is with the dynamic derived column "Island".

It's completely random. The proc can be executed 20 times and give the expected results and then the next 2 will give incorrect results.

There can be 1 or more VehicleKey/DriverKey combinations in a given date range.

This is the problem query

SELECT
     A.VehicleKey
    ,A.NodeId
    ,A.DriverKey
    ,MIN(A.StartTrip)   'StartTrip'
    ,MAX(A.EndTrip)     'EndTrip'
    ,SUM(A.PrivOdo)     'Private'
    ,SUM(A.BusOdo)      'Business'
    ,SUM(A.TravOdo)     'Travel'
    ,SUM(A.PrivOdo + A.BusOdo + A.TravOdo )'Total'
FROM
(
    SELECT
         Island = ( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey ORDER BY MONTH(StartTrip)) ) - ( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey, T.DriverKey ORDER BY T.StartTrip) )
        ,NodeId
        ,VehicleKey
        ,DriverKey
        ,StartTrip
        ,EndTrip
        ,BusOdo
        ,PrivOdo
        ,TravOdo
    FROM 
        #xYTD_BPTotals T
) AS A
GROUP BY
     A.Island
    ,A.VehicleKey
    ,A.NodeId
    ,A.DriverKey
ORDER BY 
     A.VehicleKey
    ,MIN(A.StartTrip); 

I am of the understanding that the ORDER BY should be on the outside of the derived table for it to take effect.

I think I've narrowed it down to the issue presenting itself only when a Vehicle has 2 or more DriverKey combinations.

for example, Parameters VehicleKey 4865, StartDateTime = '2016-01-01', EndDateTime = '2016-10-31' This is the correct result - including Island column

VehicleKey    NodeId    DriverKey    Island    StartTrip              EndTrip               Private    Business    Travel    Total_
4865          458       0            0         2016-09-06 14:06:08    2016-09-28 17:02:08   54.75      737.83      0         792.58
4865          458       1202         134       2016-09-29 11:10:04    2016-09-30 17:25:51   0          211.32      0         211.32
4865          458       0            27        2016-10-03 07:39:25    2016-10-14 17:00:15   0          579.81      0         579.81

and this is when it's wrong. Parameters VehicleKey 4865, StartDateTime = '2016-01-01', EndDateTime = '2016-10-31' - including Island column The first two rows here should be combined.

VehicleKey    NodeId    DriverKey    Island    StartTrip              EndTrip               Private    Business    Travel    Total_
4865          458       0            98        2016-09-06 14:06:08    2016-09-21 09:15:49   0          313.87      0         313.87
4865          458       0            -63       2016-09-21 09:21:10    2016-09-28 17:02:08   54.75      423.96      0         478.71
4865          458       1202         71        2016-09-29 11:10:04    2016-09-30 17:25:51   0          211.32      0         211.32
4865          458       0            27        2016-10-03 07:39:25    2016-10-14 17:00:15   0          579.81      0         579.81

If I show the first few rows from the derived table, I've broken down the "Island" column

SELECT
     Island = ( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey ORDER BY MONTH(StartTrip)) ) - ( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey, T.DriverKey ORDER BY T.StartTrip) )
    ,Island_x =( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey ORDER BY MONTH(StartTrip)) )
    ,Island_y = ( ROW_NUMBER() OVER (PARTITION BY T.VehicleKey, T.DriverKey ORDER BY T.StartTrip) )
    ,NodeId
    ,VehicleKey
    ,DriverKey
    ,StartTrip
    ,EndTrip
    ,BusOdo
    ,PrivOdo
    ,TravOdo
FROM 
    #xYTD_BPTotals T

The correct result should be

Island  Island_x    Island_y    NodeId  VehicleKey  DriverKey   StartTrip   EndTrip BusOdo  PrivOdo TravOdo
0   1   1   24901   4865    0   2016-09-06 14:06:08 2016-09-06 14:08:50 0   0   0
0   2   2   24901   4865    0   2016-09-06 15:39:14 2016-09-06 15:40:53 114 0   0
0   3   3   24901   4865    0   2016-09-08 11:06:43 2016-09-08 11:07:23 0   0   0
0   4   4   24901   4865    0   2016-09-08 11:12:03 2016-09-08 11:12:26 20  0   0
0   5   5   24901   4865    0   2016-09-08 11:19:20 2016-09-08 11:19:52 1   0   0
0   6   6   24901   4865    0   2016-09-08 11:26:58 2016-09-08 11:27:56 88  0   0
0   7   7   24901   4865    0   2016-09-08 11:33:40 2016-09-08 11:35:02 1   0   0
0   8   8   24901   4865    0   2016-09-12 09:08:53 2016-09-12 09:10:42 34  0   0

but I sometimes get this with the same input paramaters.

Island  Island_x    Island_y    NodeId  VehicleKey  DriverKey   StartTrip   EndTrip BusOdo  PrivOdo TravOdo
98  1   1   24901   4865    0   2016-09-06 14:06:08 2016-09-06 14:08:50 0   0   0
98  2   2   24901   4865    0   2016-09-06 15:39:14 2016-09-06 15:40:53 114 0   0
98  3   3   24901   4865    0   2016-09-08 11:06:43 2016-09-08 11:07:23 0   0   0
98  4   4   24901   4865    0   2016-09-08 11:12:03 2016-09-08 11:12:26 20  0   0
98  5   5   24901   4865    0   2016-09-08 11:19:20 2016-09-08 11:19:52 1   0   0
98  6   6   24901   4865    0   2016-09-08 11:26:58 2016-09-08 11:27:56 88  0   0
98  7   7   24901   4865    0   2016-09-08 11:33:40 2016-09-08 11:35:02 1   0   0
98  8   8   24901   4865    0   2016-09-12 09:08:53 2016-09-12 09:10:42 34  0   0

Why is the "Island" calculated column wrong? 1-1 = 0 not 98.

Where am I going wrong?


回答1:


EDIT - @YourData now looks like your raw table

Declare @YourTable table (VehicleKey int,NodeId int,DriverKey int,StartTrip datetime,EndTrip datetime,PrivOdo decimal(10,2),BusOdo decimal(10,2), TravOdo decimal(10,2))
Insert Into @YourTable values
(4865,458,0   ,'2016-09-06 14:06:08','2016-09-21 09:15:49',0    ,313.87,0),
(4865,458,0   ,'2016-09-21 09:21:10','2016-09-28 17:02:08',54.75,423.96,0),
(4865,458,1202,'2016-09-29 11:10:04','2016-09-30 17:25:51',0    ,211.32,0),
(4865,458,0   ,'2016-10-03 07:39:25','2016-10-14 17:00:15',0    ,579.81,0)

Select VehicleKey
      ,NodeID
      ,VehicleKey
      ,DriverKey
      ,StartTrip = min(StartTrip)
      ,EndTrip   = max(EndTrip)
      ,Private   = sum(PrivOdo)
      ,Business  = sum(BusOdo)
      ,Travel    = sum(TravOdo)
      ,Total     = sum(PrivOdo + BusOdo + TravOdo )
 From (
 Select  Island = ( ROW_NUMBER() OVER (PARTITION BY VehicleKey ORDER BY MONTH(StartTrip)) ) - ( ROW_NUMBER() OVER (PARTITION BY VehicleKey, DriverKey ORDER BY StartTrip) )
        ,*
 From @YourTable 
) A
Group By Island,VehicleKey,NodeID,VehicleKey,DriverKey
Order By min(StartTrip)

Returns

FYI - The sub-query produces



来源:https://stackoverflow.com/questions/40361594/tsql-order-by-on-occasion-doesnt-order-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!