TSQL Order BY有时无法正确排序

时间:2016-11-01 14:00:05

标签: sql-server-2008-r2 sql-order-by

TSQL MSSQL 2008r2

我正在重写这个问题,试图说明我试图解释的问题是什么。

我有一个存储过程,需要3个参数。 VehicleKey,StartDate和EndDateTime。我正在查询数据仓库数据库。所以数据不应该改变。

当使用相同的参数调用proc时,大多数时候结果将如预期的那样,但在某些随机的情况下,使用相同的参数,结果会有所不同。我正在查询数据WH,因此数据不会改变。

问题在于动态派生列“Island”。

这完全是随机的。 proc可以执行20次并给出预期的结果,然后接下来的2将给出不正确的结果。

在给定的日期范围内可以有1个或多个VehicleKey / DriverKey组合。

这是问题查询

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); 

我理解ORDER BY应该在派生表的外部才能生效。

我认为只有在车辆有2个或更多DriverKey组合时,我才会将其缩小到自己出现的问题。

例如,Parameters VehicleKey 4865, StartDateTime = '2016-01-01', EndDateTime = '2016-10-31' 这是正确的结果 - 包括岛列

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

这就是错误的时候。 Parameters VehicleKey 4865, StartDateTime = '2016-01-01', EndDateTime = '2016-10-31' - 包括岛柱 这里的前两行应该合并。

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

如果我显示派生表中的前几行,我已经分解了“岛”列

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

正确的结果应该是

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

但我有时会使用相同的输入参数来获得它。

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

为什么“Island”计算列错了? 1-1 = 0不是98。

我哪里错了?

1 个答案:

答案 0 :(得分:0)

  

编辑 - @YourData现在看起来像您的原始表

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)

返回

enter image description here

FYI - 子查询生成

enter image description here