我的PostgreSQL数据库中有以下表:

  1. 建筑
 id |           name           | abbreviation 
----+--------------------------+--------------
 31 | 4705 Fifth Avenue - Dept | 4705FIFTH-D
 28 | 4705 Fifth Avenue        | 4705FIFTH
...
  1. 建筑_网络
 id  | 建筑_id | 网络_id 
-----+--------------+-------------
 143 |           31 |         159
 144 |           31 |         160
 147 |           28 |         153
 148 |           28 |         154
 149 |           28 |         155
 159 |           31 |         179
...
  1. 网络
 id  |          name          | display_name 
-----+------------------------+--------------------
 179 | 4705FIFTH-D -- fmcs    | fmcs (staff)
 153 | 4705FIFTH -- onboard   | onboard (residents)
 154 | 4705FIFTH -- private   | private (residents)
 155 | 4705FIFTH -- public    | public (residents)
 159 | 4705FIFTH-D -- onboard | onboard (staff)
 160 | 4705FIFTH-D -- private | private (staff
...

我正在try 更新建筑_网络表,以便所有网络(包括名称中包含-D的网络)都与名称中没有- Dept的类似建筑相关联.

使用上面的例子,建筑_网络表理想情况下应该是这样的:

 id  | 建筑_id | 网络_id 
-----+--------------+-------------
 143 |           28 |         159
 144 |           28 |         160
 147 |           28 |         153
 148 |           28 |         154
 149 |           28 |         155
 159 |           28 |         179
...

我意识到这可以在示例中逐行完成,但除了我在本示例中提供的建筑物和网络之外,还有许多额外的建筑物和网络. 因此,单个查询可以节省很多时间.

其他建筑物各不相同,但每个建筑物总是有两个. 第一个子集是名称末尾有- Dept的子集,例如4705 Fifth Avenue - Dept. -Dept建筑物总是有一个以-D结尾的缩写,比如4705FIFTH-D. 建筑物的第二个子集的名称和缩写分别没有- Dept-D4705 Fifth Avenue4705FIFTH.

此外,总有两种网络名称. 其中一个子集是名称第一部分末尾有-D的那些,例如4705FIFTH-D -- onboard. 另一个子集没有-D,例如4705FIFTH -- onboard.

我try 过这个:

UPDATE 建筑_网络 bn
SET 建筑_id = subquery2.building_id
FROM (
  SELECT b2.id AS building_id, b2.name, b2.abbreviation, bn2.网络_id
  FROM 建筑 b2
  INNER JOIN 建筑_网络 bn2
  ON bn2.建筑_id = b2.id
  WHERE b2.abbreviation NOT LIKE '%-D'
) AS subquery2
INNER JOIN 建筑 b
ON b.id = subquery2.building_id
WHERE replace(b.abbreviation, '-D', '') LIKE subquery2.abbreviation
OR b.abbreviation LIKE subquery2.abbreviation;

这看起来很接近,但它将建筑_id个值中的所有值设置为单个值(例如,除了本例中所示的记录之外,还有400多条记录),而不是每个建筑物.

此查询会产生相同(不期望的)结果:

UPDATE 建筑_网络
SET 建筑_id = (
  SELECT b2.id 
  FROM 建筑 b2 
  WHERE b2.abbreviation = REPLACE(b.abbreviation, '-D', '')
)
FROM 建筑_网络 bn
INNER JOIN 建筑 b 
ON b.id = bn.建筑_id
WHERE b.abbreviation LIKE '%-D';

我哪里错了?

推荐答案

try 一下, idea 是只拥有正确的id,然后加入正确的缩写

update buildings_networks  
set buildings_id = right_ids.id
from buildings 
join (
    select id, abbreviation 
      from buildings
     where abbreviation not like '%-D'
) right_ids on buildings.abbreviation like concat(right_ids.abbreviation, '%')
where buildings.id = buildings_networks.buildings_id

Sql相关问答推荐

Oracle SQL中多个函数上的SON构建不会以良好的格式结束

在SELECT陈述中使用子查询提高查询性能

SQL查询以创建手头的流动余额?

SQL查询视图与连接?

删除MariaDB数据库中的JSON数据

LEFT JOIN不显示计数0我期望的方式

如何根据给定条件PostgreSQL迭代减少组中的行数

如何将`now()`作为SQL插入语句的一部分?

TSQL如何为群分配号码

基于开始/结束日期重叠的BigQuery突发行

如何根据 SQL 中的阈值标记一个集群中的所有值?

用替代方案替换 SQL Cursor 以提高性能

具有多个表 JOINS 的 STRING_AGG 的替代方法 (SQL Server 2016)

SQL Server: 将JSON对象数组转换为表格格式

Postgres更新增量之间的差异

SQL 函数 DIFFERENCE 返回有趣的分数

如何在 DAX 中通过 Window 函数应用订单

如何更改 duckdb R 中的数据约束

多列上的 SQL UNIQUE 约束 - 它们的组合必须是唯一的还是至少其中之一?

创建一个将层次 struct 级别放入列中的查询