我有一张跟我一样的桌子

CREATE TABLE
    IF NOT EXISTS t1
(
    ID                bigserial PRIMARY KEY,
    name              text,
    lat               varchar(255),
    long              varchar(255),
    rel_id varchar(255)
);

在这里,LATH、LONG列中某些值为空或空白.我要做的是判断rel_id是否与映射项的键值匹配,如果lat或long为空或空,则从map中设置其相应值,如下所示:

"1708237": {40.003196, 68.766304},
"1703206": {40.855638, 71.951236},
"1703217": {40.789588, 71.703445},
"1703209": {40.696825, 71.893556},
"1703230": {40.692121, 72.072769},
"1703202": {40.777208, 72.195201},
"1703214": {40.912185, 72.261577},
"1703232": {40.967893, 72.411201},
"1703203": {40.814196, 72.464561},
"1703211": {40.733920, 72.635528},
"1703220": {40.769949, 72.872072},
"1703236": {40.644870, 72.589310},
"1703224": {40.667720, 72.237619},
"1703210": {40.609053, 72.487692},
"1703227": {40.522460, 72.306502},
"1730212": {40.615228, 71.140965},
"1730215": {40.438027, 70.528916},
"1730209": {40.495830, 71.219648},
"1730203": {40.463302, 71.456543},
"1730224": {40.368501, 71.201116},
"1730242": {40.646348, 71.658763},

这样表中就不会有空值.伪码可能如下所示:

coordinates = {
"1708237": {lat: 40.003196,long: 68.766304},
"1703206": {lat: 40.855638,long: 71.951236},
"1703217": {lat: 40.789588,long: 71.703445}
}

for values in results {
    if (values.lat == Null or values.long Null) {
        values.lat = coordinates[values.rel_id].lat;
        values.long = coordinates[values.rel_id].long;
    }
}

我在SQL中需要这样的逻辑.谢谢.

我试过了,但我做不到:

DO
$$
    DECLARE
        coordinates jsonb := '[
          {
            "rel_id": "1",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "2",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "3",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "4",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "5",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "6",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "7",
            "lat": 1231.123,
            "long": 1423.2342
          },
          {
            "rel_id": "8",
            "lat": 1231.123,
            "long": 1423.2342
          }
        ]'::jsonb;
    BEGIN

        UPDATE t1
        SET lat  = ci.clat,
            long = ci.clong
        from (select json_array_elements(coordinates) ->> 'rel_id' as crel_id, 'lat' as clat, 'long' as clong) as ci
        WHERE t1.rel_id = ci.crel_id && (t1.long is NULL or t1.lat is NULL);
    END
$$;

我有一张恒定的json坐标 map .我要做是更新LATH和LONG值,其中记录的rel_id与coordinates映射中的ID匹配,且LATE或LONG值为空.

推荐答案

DB fiddle

步骤:

  1. 读取输入jsonb并将crel_idclatclong值转换为单独的列.我会说这是查询中最棘手的部分.
  2. 使用json_data表中的值更新t1表.如果存在t1.latt1.long为空或Null,则更新值.

最后的程序可能是:

DO
$$
    DECLARE
        coordinates jsonb := '[
          {
            "rel_id": "1708237",
            "lat": 1,
            "long": 2
          },
          {
            "rel_id": "1703206",
            "lat": 3,
            "long": 4
          },
          {
            "rel_id": "1703217",
            "lat": 5,
            "long": 6
          },
          {
            "rel_id": "1703209",
            "lat": 7,
            "long": 8
          },
          {
            "rel_id": "1703230",
            "lat": 9,
            "long": 10
          }
        ]'::jsonb;
    BEGIN

        update t1
        set lat  = json_data.clat,
            long = json_data.clong
        from (select 
                 coords->'rel_id' #>> '{}' as crel_id, --convert jsonb value to string
                 coords->'lat' as clat,
                 coords->'long' as clong
              from (select jsonb_array_elements(coordinates) as coords) 
              as coords_data)
        as json_data
        where t1.rel_id = json_data.crel_id and
          -- check value may be null or empty for both 'lat' and 'long' columns
          (t1.long is null or t1.long = '' or t1.lat is null or t1.lat = '');
    END
$$;

Sql相关问答推荐

在postgresql中使用来自另一个字段的日期名称作为JSONB查询中的关键字

SQL:创建查询以添加减少的总数

在数据分区内执行确定

在多个联合中使用相同的SELECT SQL查询

转换表中的数据

如何用客户名称计算sum(dr)和sum(cr)

按属性值 Select 数组元素Postgres Jsonb

用于SQL协助的XQUERY()

查找滑动窗口框架中的最大和最小列值

Postgresql - WHERE 中的 MAX 标准 - 初学者问题

日期逻辑(查找过go 90 天内的第一个匹配行)

如何在 SQL Server 中解决这个复杂的窗口查询?

什么是 100.它与 100 有什么区别?

INSERT INTO 语法

删除重复记录但保留最新的SQL查询

所有列分组的简写?

为什么 get_json_object() 无法从存储在 Hive SQL 表中的 JSON 中提取值?

如何 Select 一列具有最小值而另一列具有给定值的记录?

奇怪的甲骨文行为

SQL/Postgres:按日期和其他属性对相关性能进行分组