1

最初的问题如下: SQL AdvancedQuery建议在讨论这个问题之前先看一下最初的问题,因为它包含相关信息。这个问题提出了以下问题并提供了以下信息;

  1. MMSI 编号是代表船舶的唯一编号。一艘船以独特的消息类型发送不同的信息。我只对 Message_ID 1 和 3 感兴趣,因为它们具有纬度和纵向信息。

    MMSI 将再次出现在该数据库中(如上面的数据所示)(如果您想查看此数据,可以通过链接找到)问题是,我需要有关船舶的信息,不幸的是,该信息仅在 Message_ID 5 中可用。例如 Vessel_name 和 Ship_type。

  2. Ship_Type 可能会改变!在这种情况下,它必须反映较晚的日期

  3. 我只需要以下经纬度范围内的船舶:纬度> 55且纬度<85且经度> 50且经度< 141;

****这是改变的部分!我现在需要在具有正确约束的 MMSI 中共享的所有记录。例如以下记录:****

MMSI     Message_ID    Time     Ship_Type  Vessel_Name   Latitude   Longitude

2225555      1       2012-09-01     NULL      NULL       25.432345  145.123343

由于 MMSI 编号 2225555 在指定的纬度和经度范围内有记录,因此将保留上次忽略的信息。

以下查询适用于最后一个问题中的所有规范:SQL AdvancedQuery

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

我只需要稍微调整一下。我不是程序员..所以目前无法为我调整这种复杂性的查询..谢谢..

4

2 回答 2

0

您需要另一个连接到同一个表,以使用现有查询结果中的 MMSI 拉回所有记录。这样的事情应该这样做:

; 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

编辑(从发条缪斯反馈后):

当船舶在所需区域内多次报告时,您的原始查询将返回重复的行。要摆脱这种情况,只需在 CTE 位置使用 DISTINCT:

; 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
于 2013-09-18T13:22:09.660 回答
0
; 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

现在正在使用第三个 CTE。

  1. valid_positions:坐标符合您的标准的任何Message_ID记录,对于任何 2)
  2. positions: 所有Message_ID等于 1 或 3的记录,并且MMSI对应的有记录valid_positions
  3. details: 和以前一样。显示“最新”船舶/船舶详细信息 ( Message_ID= 5)
于 2013-09-18T13:42:28.890 回答