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.
valid_positions: any records where the co-ordinates fit your criteria, for anyMessage_ID2)positions: all records whereMessage_IDequals 1 or 3 and there is a record in correspondingMMSIinvalid_positionsdetails: 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"