Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 甲骨文';无效标识符';在子查询中_Sql_Oracle_Oracle11g - Fatal编程技术网

Sql 甲骨文';无效标识符';在子查询中

Sql 甲骨文';无效标识符';在子查询中,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,当子查询引用外部查询中的列时,我在将视图从PostgreSQL转换为Oracle时遇到问题 这个问题似乎已经在这里讨论过好几次了,但是我无法得到任何修复来处理我的特定查询 查询的目的是获取移动设备上一次记录的位置,并获取距离最近的检查点/地理边界的距离(以KM为单位),它引用3个单独的表:设备、设备位置和检查点 SELECT d.id, dl.latitude AS last_latitude, dl.longitude AS last_longitude, (

当子查询引用外部查询中的列时,我在将视图从PostgreSQL转换为Oracle时遇到问题

这个问题似乎已经在这里讨论过好几次了,但是我无法得到任何修复来处理我的特定查询

查询的目的是获取移动设备上一次记录的位置,并获取距离最近的检查点/地理边界的距离(以KM为单位),它引用3个单独的表:设备、设备位置和检查点

SELECT 
    d.id,
    dl.latitude AS last_latitude,
    dl.longitude AS last_longitude,
    (SELECT * /* Get closest 'checkpoint' to the last device position by calculating the Great-circle distance */
    FROM (
        SELECT
            6371 * acos(cos(dl.latitude / (180/acos(-1))) * cos(checkpoints.latitude / (180/acos(-1))) * cos((checkpoints.longitude / (180/acos(-1))) - (dl.longitude / (180/acos(-1)))) + sin(dl.latitude  / (180/acos(-1))) * sin(checkpoints.latitude / (180/acos(-1)))) AS distance
        FROM checkpoints
        ORDER BY distance)
    WHERE ROWNUM = 1) AS distance_to_checkpoint
FROM devices d
LEFT JOIN ( /* Get the last position of the device */
    SELECT l.id,
        l.time,
        l.latitude,
        l.longitude,
        l.accuracy
    FROM device_locations l
    WHERE l.ROWID IN (SELECT MAX(ROWID) FROM device_locations GROUP BY id) 
    ORDER BY l.id, l.time DESC) dl 
ON dl.id = d.id;
我在这方面已经坚持了一段时间,希望有人能把我带上正确的道路,谢谢。

我看到两个问题:

  • 最后选择列后的额外逗号:
    作为到检查点的距离,
  • 外部选择列引用内部表
    device\u locations l
    ,而不是派生表
    dl
    -示例:
    l.latitude
    应为
    dl.latitude
  • 我看到两个问题:

  • 最后选择列后的额外逗号:
    作为到检查点的距离,
  • 外部选择列引用内部表
    device\u locations l
    ,而不是派生表
    dl
    -示例:
    l.latitude
    应为
    dl.latitude

  • 首先:查询不会获取最后一个设备位置。它根据
    ID
    获取具有最高
    ROWID
    的记录,该记录可能恰好是最新条目,但根本不能保证是最新条目

    那么,您很可能对范围有问题。不幸的是,名称仅在一个级别深度有效,这是一个令人恼火的限制
    dl.latitude
    等在子查询中可能无效,因为它实际上是子查询中的子查询。不管怎样,您想要得到的是最小距离,您可以使用
    MIN
    轻松获得该距离

    在标准SQL中,子查询中的
    ORDER BY
    是多余的。Oracle为他们的
    ROWNUM
    技术提供了一个例外,但我不会使用这个。(如前所述,获取最小值甚至很笨拙。)外部联接中的
    ORDER BY
    无论如何都是多余的

    这就是我处理问题的方法:

    select
      d.id as device_id,
      dl.latitude as last_latitude,
      dl.longitude as last_longitude,
      (
        select min(6371 *
                   acos(cos(dl.latitude / (180/acos(-1))) *
                        cos(cp.latitude / (180/acos(-1))) *
                        cos((cp.longitude / (180/acos(-1))) - (dl.longitude / (180/acos(-1))))
                        + 
                        sin(dl.latitude / (180/acos(-1))) *
                        sin(cp.latitude / (180/acos(-1)))
                       )
                   )
        from checkpoints cp
      ) as distance
    from devices d
    left join 
    (
      select 
        id as device_id, latitude, longitude, time,
        max(time) over (partition by id) as max_time
      from device_locations
    ) dl on dl.device_id = d.id and dl.time = dl.max_time;
    

    首先:查询不会获取最后一个设备位置。它根据
    ID
    获取具有最高
    ROWID
    的记录,该记录可能恰好是最新条目,但根本不能保证是最新条目

    那么,您很可能对范围有问题。不幸的是,名称仅在一个级别深度有效,这是一个令人恼火的限制
    dl.latitude
    等在子查询中可能无效,因为它实际上是子查询中的子查询。不管怎样,您想要得到的是最小距离,您可以使用
    MIN
    轻松获得该距离

    在标准SQL中,子查询中的
    ORDER BY
    是多余的。Oracle为他们的
    ROWNUM
    技术提供了一个例外,但我不会使用这个。(如前所述,获取最小值甚至很笨拙。)外部联接中的
    ORDER BY
    无论如何都是多余的

    这就是我处理问题的方法:

    select
      d.id as device_id,
      dl.latitude as last_latitude,
      dl.longitude as last_longitude,
      (
        select min(6371 *
                   acos(cos(dl.latitude / (180/acos(-1))) *
                        cos(cp.latitude / (180/acos(-1))) *
                        cos((cp.longitude / (180/acos(-1))) - (dl.longitude / (180/acos(-1))))
                        + 
                        sin(dl.latitude / (180/acos(-1))) *
                        sin(cp.latitude / (180/acos(-1)))
                       )
                   )
        from checkpoints cp
      ) as distance
    from devices d
    left join 
    (
      select 
        id as device_id, latitude, longitude, time,
        max(time) over (partition by id) as max_time
      from device_locations
    ) dl on dl.device_id = d.id and dl.time = dl.max_time;
    

    这是我另一个答案的后续。为了获得距离最小的
    检查点
    记录,您需要加入表并再次使用窗口函数来选择最佳记录。例如:

    select
      device_id,
      last_latitude,
      last_longitude,
      checkpoint_latitude,
      checkpoint_longitude,
      distance
    from
    (
      select
        device_id,
        last_latitude,
        last_longitude,
        checkpoint_latitude,
        checkpoint_longitude,
        distance,
        min(distance) over (partition by device_id) as min_distance
      from
      (
        select
          d.id as device_id,
          dl.latitude as last_latitude,
          dl.longitude as last_longitude,
          cp.latitude as checkpoint_latitude,
          cp.longitude as checkpoint_longitude,
          6371 *
          acos(cos(dl.latitude / (180/acos(-1))) *
               cos(cp.latitude / (180/acos(-1))) *
               cos((cp.longitude / (180/acos(-1))) - (dl.longitude / (180/acos(-1))))
               + 
               sin(dl.latitude / (180/acos(-1))) *
               sin(cp.latitude / (180/acos(-1)))
              ) as distance
        from devices d
        left join 
        (
          select 
            id as device_id, latitude, longitude, time,
            max(time) over (partition by id) as max_time
          from device_locations
        ) dl on dl.device_id = d.id and dl.time = dl.max_time
        cross join checkpoints cp
      )
    )
    where (distance = min_distance) or (distance is null and min_distance is null);
    

    从Oracle 12c开始,使用
    交叉应用
    外部应用
    编写此类查询更容易。

    这是我的另一个答案的后续内容。为了获得距离最小的
    检查点
    记录,您需要加入表并再次使用窗口函数来选择最佳记录。例如:

    select
      device_id,
      last_latitude,
      last_longitude,
      checkpoint_latitude,
      checkpoint_longitude,
      distance
    from
    (
      select
        device_id,
        last_latitude,
        last_longitude,
        checkpoint_latitude,
        checkpoint_longitude,
        distance,
        min(distance) over (partition by device_id) as min_distance
      from
      (
        select
          d.id as device_id,
          dl.latitude as last_latitude,
          dl.longitude as last_longitude,
          cp.latitude as checkpoint_latitude,
          cp.longitude as checkpoint_longitude,
          6371 *
          acos(cos(dl.latitude / (180/acos(-1))) *
               cos(cp.latitude / (180/acos(-1))) *
               cos((cp.longitude / (180/acos(-1))) - (dl.longitude / (180/acos(-1))))
               + 
               sin(dl.latitude / (180/acos(-1))) *
               sin(cp.latitude / (180/acos(-1)))
              ) as distance
        from devices d
        left join 
        (
          select 
            id as device_id, latitude, longitude, time,
            max(time) over (partition by id) as max_time
          from device_locations
        ) dl on dl.device_id = d.id and dl.time = dl.max_time
        cross join checkpoints cp
      )
    )
    where (distance = min_distance) or (distance is null and min_distance is null);
    

    从Oracle 12c开始,使用
    交叉应用
    外部应用
    ,这样的查询更容易编写。

    这里有一个额外的逗号
    作为距离检查点,
    查询不获取最后的设备位置。它根据
    ID
    获取具有最高
    ROWID
    的记录,该记录可能恰好是最新条目,但根本不能保证是最新条目。您如何确定最后一个位置?通过
    时间
    列?不管名称如何,
    device\u locations
    中的
    ID
    不是表的ID?而是设备ID?你应该彻底改变这个名字。顺便说一句,子查询中的
    ORDER BY
    子句是完全多余的。您使用的是哪种Oracle版本?您想查看所有设备ID,即使是没有
    设备位置记录的设备ID也不例外?这里有一个额外的逗号
    作为距离检查点,
    查询不会获取最后的设备位置。它根据
    ID
    获取具有最高
    ROWID
    的记录,该记录可能恰好是最新条目,但根本不能保证是最新条目。您如何确定最后一个位置?通过
    时间
    列?不管名称如何,
    device\u locations
    中的
    ID
    不是表的ID?而是设备ID?你应该彻底改变这个名字。顺便说一句,子查询中的
    ORDER BY
    子句是完全多余的。您使用的是哪个Oracle版本?您想查看所有设备ID,即使是那些没有
    设备位置记录的设备ID?谢谢,我已经解决了这些问题,但在大圆距离子查询中仍然有一个无效标识符:ORA-00904:“DL”“LATITUDE”:无效标识符00904.00000-“%s:无效标识符”*原因:*操作:第8行错误列:192谢谢我已修复了这些问题,但在大圆距离子查询ORA-00904中仍然存在无效标识符:“DL”“LATITUDE”:无效标识符00904.00000-“%s:无效标识符”“*原因:*操作:第8行错误列:192这似乎解决了我的问题,非常感谢您的帮助。我确实有一个疑问