Skip to content Skip to sidebar Skip to footer

SQL Query Adjustment

The initial question was as follows: SQL AdvancedQuery It is recommended to take a look at the initial question before going at this one, as it holds pertinent information. This qu

Solution 1:

; WITH valid_positions AS (
  SELECT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Latitude  > 55
  AND    Latitude  < 85
  AND    Longitude > 50
  AND    Longitude < 141
)
, positions AS (
  SELECT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID IN (1, 3)
  AND    EXISTS (
           SELECT *
           FROM   valid_positions
           WHERE  valid_positions.MMSI = DecodedCSVMessages_Staging.MMSI
         )
)
, details AS (
  SELECT MMSI
       , Ship_Type
       , Vessel_Name
       , Row_Number() OVER (PARTITION BY MMSI ORDER BY "Time" DESC) As row_num
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID = 5
)
SELECT positions.MMSI
     , positions.Message_ID
     , positions."Time"
     , details.Ship_Type
     , details.Vessel_Name
     , positions.Latitude
     , positions.Longitude
FROM   positions
 INNER
  JOIN details
    ON details.MMSI    = positions.MMSI
   AND details.row_num = 1 -- Limit to "latest" ship details per MMSI

There's now a 3rd CTE being used.

  1. valid_positions: any records where the co-ordinates fit your criteria, for any Message_ID 2)
  2. positions: all records where Message_ID equals 1 or 3 and there is a record in corresponding MMSI in valid_positions
  3. details: unchanged from before. Shows the "latest" ship/vessel details (Message_ID = 5)

Solution 2:

You need another join to the same table to pull back all the records with an MMSI that is in the result of your existing query. Something like this should do it:

; WITH positions AS (
  SELECT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID IN (1, 3)
  AND    Latitude  > 55
  AND    Latitude  < 85
  AND    Longitude > 50
  AND    Longitude < 141
)
, all_positions AS (
  SELECT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID IN (1, 3)
)
, details AS (
  SELECT MMSI
       , Ship_Type
       , Vessel_Name
       , Row_Number() OVER (PARTITION BY MMSI ORDER BY "Time" DESC) As row_num
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID = 5
)
SELECT all_positions.MMSI
     , all_positions.Message_ID
     , all_positions."Time"
     , details.Ship_Type
     , details.Vessel_Name
     , all_positions.Latitude
     , all_positions.Longitude
FROM   positions
 INNER
  JOIN details
    ON details.MMSI    = positions.MMSI
   AND details.row_num = 1 -- Limit to "latest" ship details per MMSI
 INNER
  JOIN all_positions 
    ON positions.MMSI    = all_positions.MMSI

EDIT (after feedback from Clockwork-Muse):

Your original query will return duplicate rows when a ship reports more than once from within the desired area. To get rid of this, just use DISTINCT in the positions CTE:

; WITH positions AS (
  SELECT DISTINCT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID IN (1, 3)
  AND    Latitude  > 55
  AND    Latitude  < 85
  AND    Longitude > 50
  AND    Longitude < 141
)
, all_positions AS (
  SELECT MMSI
       , Message_ID
       , "Time"
       , Latitude
       , Longitude
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID IN (1, 3)
)
, details AS (
  SELECT MMSI
       , Ship_Type
       , Vessel_Name
       , Row_Number() OVER (PARTITION BY MMSI ORDER BY "Time" DESC) As row_num
  FROM   dbo.DecodedCSVMessages_Staging
  WHERE  Message_ID = 5
)
SELECT all_positions.MMSI
     , all_positions.Message_ID
     , all_positions."Time"
     , details.Ship_Type
     , details.Vessel_Name
     , all_positions.Latitude
     , all_positions.Longitude
FROM   positions
 INNER
  JOIN details
    ON details.MMSI    = positions.MMSI
   AND details.row_num = 1 -- Limit to "latest" ship details per MMSI
 INNER
  JOIN all_positions 
    ON positions.MMSI    = all_positions.MMSI

Post a Comment for "SQL Query Adjustment"