SQL使用可选参数SP从多个内部联接中选择最新行

时间:2013-12-30 10:01:59

标签: sql sql-server stored-procedures

我有以下表格:

Locations
_________________
Location_ID,
TrackingVehicle_ID,
GPS_Time,
Longitude,
Latitude,
Speed,
Angle,
LocationStatus_No,
IgnitionStatus_No,
Address,
Distance,
Message_Type_No,
StreetSpeed,
Vehicle_ID,
Driver_ID.


Vehicles
___________
Vehicle_ID,
Company_ID,
PlateNumber,
VehicleType_No,
VehicleSubType_No,
Status_ID.


TrackingVehicles
___________________
TrackingVehicle_ID,
Fleet_ID,
Vehicle_ID,
Driver_ID,
MaxSpeed,
Vehicle_SN,
NavDevice_ID,
Latest_LocationID,
Latest_GPS_Time.


VehicleFences
_______________
VehicleFecne_ID,
GeoFence_ID,
Vehicle_ID.

我想返回特定公司ID,车队,围栏和IgnitionStatus的车辆。 除了companyID,

之外,这些参数可以为null

我尝试了以下内容:

ALTER PROCEDURE [dbo].[testselectVehicle]
@companyId int,
   @fleetId int,
   @geofenceId int,
   @ignStatId int      
AS
BEGIN
declare @str [nvarchar](MAX) = '',
@qur [nvarchar](MAX)

IF @fleetId is not null
    BEGIN
    SET @str =@str + ' and TrackingVehicles.Fleet_ID = ''' + Convert(nvarchar,         @fleetId) + ''''
    END
    IF @geofenceId is not null
    BEGIN
    SET @str =@str + '  and vehiclefences.geofence_id = '''+ Convert(nvarchar,     @geofenceId)+''''
    END
    IF @ignStatId is not null
    BEGIN
    SET @str =@str + '  and  Locations.IgnitionStatus_No = '''+ Convert(nvarchar,     @ignStatId) +''''
    END


 set @qur =    'SELECT dbo.Locations.GPS_Time,
                       dbo.Vehicles.PlateNumber,
                       dbo.Locations.Address,
                       dbo.Locations.Speed,
                       dbo.Locations.Longitude,
                       dbo.Locations.Latitude,
                       dbo.Locations.IgnitionStatus_No
                 FROM  dbo.Locations
                 INNER JOIN  dbo.TrackingVehicles ON
             dbo.Locations.TrackingVehicle_ID = dbo.TrackingVehicles.TrackingVehicle_ID 
                INNER JOIN dbo.Vehicles ON
            dbo.Locations.Vehicle_ID =     dbo.Vehicles.Vehicle_ID AND
            dbo.TrackingVehicles.Vehicle_ID = dbo.Vehicles.Vehicle_ID
                 INNER JOIN dbo.VehicleFences ON
            dbo.Vehicles.Vehicle_ID = dbo.VehicleFences.Vehicle_ID 
            where Vehicles.Company_ID = '

set @qur = @qur + Convert(nvarchar,@companyId)                      
set @qur = @qur + @str

exec(@qur)


END

但7500000记录返回的原因是GPS_Time,经度&纬度可能具有同一车辆的多个值,

我需要使用最新位置(长& lat)和最新的GPS_time返回车辆详细信息

2 个答案:

答案 0 :(得分:0)

要仅包含每辆车的最后一次GPS_Time,您可以将内部联接添加到每辆车最后一次GPS_Time的子查询中:

...INNER JOIN 
    (SELECT TrackingVehicle_ID, MAX(GPS_Time) GPS_Time 
    FROM Locations GROUP BY TrackingVehicle_ID) X
ON X.TrackingVehicle_ID = Locations.TrackingVehicle_ID AND X.GPS_Time= Locations.GPS_Time

答案 1 :(得分:0)

您可以使用row_number()功能枚举位置,然后选择第一个:

SELECT l.GPS_Time, v.PlateNumber, l.Address, l.Speed, l.Longitude, l.Latitude, l.IgnitionStatus_No
FROM (select l.*,
             row_number() over (partition by TrackingVehicle_ID
                                order by GPS_Time desc
                               ) as seqnum
      from dbo.Locations l
     ) l inner join
     dbo.TrackingVehicles tv
     on l.TrackingVehicle_ID = tv.TrackingVehicle_ID and l.seqnum = 1 inner join
     dbo.Vehicles v
     on tv.Vehicle_ID = v.Vehicle_ID inner join
     dbo.VehicleFences vf
     on v.Vehicle_ID = vf.Vehicle_ID 
where Vehicles.Company_ID . . .

我还通过使用表别名并在join表上删除额外的冗余Vehicles条件来简化查询。