如何在 SQLite 中使用相关子查询更新多个列?

Bre*_*els 5 sqlite sql-update

我想使用相关子查询更新表中的多个列。更新单列很简单:

UPDATE route
SET temperature = (SELECT amb_temp.temperature
                   FROM amb_temp.temperature
                   WHERE amb_temp.location = route.location)
Run Code Online (Sandbox Code Playgroud)

但是,我想更新路由表的几列。由于子查询实际上要复杂得多(使用SpatiaLite函数与嵌套子查询 JOIN ),我想避免像这样重复它:

UPDATE route
SET
  temperature = (SELECT amb_temp.temperature
                 FROM amb_temp.temperature
                 WHERE amb_temp.location = route.location),
  error = (SELECT amb_temp.error
           FROM amb_temp.temperature
           WHERE amb_temp.location = route.location),
Run Code Online (Sandbox Code Playgroud)

理想情况下,SQLite 会让我做这样的事情:

UPDATE route
SET (temperature, error) = (SELECT amb_temp.temperature, amb_temp.error
                            FROM amb_temp.temperature
                            WHERE amb_temp.location = route.location)
Run Code Online (Sandbox Code Playgroud)

唉,这是不可能的。这可以用另一种方式解决吗?

到目前为止,这是我一直在考虑的:

  • 按照本答案中的建议使用 INSERT OR REPLACE 。似乎不可能在子查询中引用路由表。
  • 在 UPDATE 查询前面加上WITH 子句,但我认为这在这种情况下没有用。

为了完整起见,这是我正在处理的实际 SQL 查询:

UPDATE route SET (temperature, time_distance) = ( -- (C)
  SELECT  -- (B)
    temperature.Temp,
    MIN(ABS(julianday(temperature.Date_HrMn)
            - julianday(route.date_time))) AS datetime_dist
  FROM temperature
    JOIN (
      SELECT  -- (A)
        *, Distance(stations.geometry,route.geometry) AS distance
      FROM stations
      WHERE EXISTS (
        SELECT 1
        FROM temperature
        WHERE stations.USAF = temperature.USAF
              AND stations.WBAN_ID = temperature.NCDC
        LIMIT 1
      )
      GROUP BY stations.geometry
      ORDER BY distance
      LIMIT 1
  ) tmp
  ON tmp.USAF = temperature.USAF
     AND tmp.WBAN_ID = temperature.NCDC
)
Run Code Online (Sandbox Code Playgroud)

此查询的高级描述:

  • 使用geometry(=经度和纬度)并date_timeroute表中,
  • (A) 找到气象站(stations表,由 USAF 和 NCDC/WBAN_ID 列唯一标识)
    • 最接近给定的经度/纬度 ( geometry)
    • temperature表中列出的温度
  • (B) 查找temperature表格行
    • 对于上面找到的气象站
    • 在时间上最接近给定时间戳
  • (C) 在route表中存储温度和“time_distance”

jhn*_*hnc 0

UPDATE route
SET
  temperature = q.temperature,
  error = q.error
FROM ( SELECT * FROM amb_temp ) q
WHERE q.location = route.location
Run Code Online (Sandbox Code Playgroud)