从子查询postgresql更新列中的所有字段

从子查询postgresql更新列中的所有字段,postgresql,sql-update,subquery,Postgresql,Sql Update,Subquery,我有一个表,比如说buchas,包含一个产品列表。我必须创建另一个表bucas\u type,其中包含bucas中产品的类型(如果愿意,可以使用类) 现在我必须通过添加一个type\u id列来引用buchas中的产品类别 因此,我的问题可以分为两部分: 我需要一个子查询来“猜测”产品类型的名称。这应该有点容易,因为产品的名称包含其类型的名称。例如: -----------------Name----------------- | ---Type--- BUC

我有一个表,比如说
buchas
,包含一个产品列表。我必须创建另一个表
bucas\u type
,其中包含
bucas
中产品的类型(如果愿意,可以使用类)

现在我必须通过添加一个
type\u id
列来引用
buchas
中的产品类别

因此,我的问题可以分为两部分:

我需要一个子查询来“猜测”产品类型的名称。这应该有点容易,因为产品的名称包含其类型的名称。例如:

   -----------------Name----------------- | ---Type---
               BUCHA GOB 1600                   GOB
问题是我有一个GOB类型(2),它会把事情搞砸。(我还有其他类似类型的人提出了同样的问题)

到目前为止,我得到了:

SELECT buchas_type.id 
FROM buchas_type 
  JOIN buchas ON buchas.description LIKE '%' || buchas_type.type || '%'
ORDER BY length(type) desc LIMIT 1;
这将解决相似类型的问题,因为它返回最长的匹配。但是,我需要一个
WHERE
子句,否则我总是得到相同的
buchas\u type\u id
。例如,如果我尝试
其中buchas.id=50
,我会得到一个正确的结果

问题的第二部分是
UPDATE
命令本身。我需要从(1)中显示的子查询中填写最近创建的
buchas\u type\u id
。因此,对于
buchas
中的每一行,它必须使用当前行的描述作为参数来搜索
buchas\u type
中的类型


如何实现这一点?

假设您在
buchas
上有一个主键,那么问题的第一部分可以通过
上的distinct解决

select * from buchas;

 buchas_id |    description    | buchas_type_id 
-----------+-------------------+----------------
         1 | BUCHA GOB 1600    |               
         2 | BUCHA GOB(2) 1700 |               
(2 rows)

select * from buchas_type;

 buchas_type_id |  type  
----------------+--------
              1 | GOB
              2 | GOB(2)
(2 rows)

select distinct on (b.buchas_id)  b.buchas_id, t.buchas_type_id, b.description, t.type
  from buchas b 
  join buchas_type t 
    on b.description ilike '%'||t.type||'%' 
 order by b.buchas_id, length(t.type) desc;

 buchas_id | buchas_type_id |    description    |  type  
-----------+----------------+-------------------+--------
         1 |              1 | BUCHA GOB 1600    | GOB
         2 |              2 | BUCHA GOB(2) 1700 | GOB(2)
(2 rows)
解决此问题后,您可以从
执行更新:

with type_map as (                                              
  select distinct on (b.buchas_id)  b.buchas_id, t.buchas_type_id
    from buchas b 
    join buchas_type t 
      on b.description ilike '%'||t.type||'%' 
   order by b.buchas_id, length(t.type) desc
)
update buchas
   set buchas_type_id = t.buchas_type_id
  from type_map t
 where t.buchas_id = buchas.buchas_id;

UPDATE 2

select * from buchas b join buchas_type t on t.buchas_type_id = b.buchas_type_id;
 buchas_id |    description    | buchas_type_id | buchas_type_id |  type  
-----------+-------------------+----------------+----------------+--------
         1 | BUCHA GOB 1600    |              1 |              1 | GOB
         2 | BUCHA GOB(2) 1700 |              2 |              2 | GOB(2)
(2 rows)

谢谢你,迈克,它工作得很好。在等待帮助的过程中,我一直试图解决我的问题,并怀疑我的子查询才是真正的问题。你的回答证明是对的。我不太明白
Distinct On
语句是如何解决类型相似性问题的。你介意解释一下吗?非常感谢您的帮助。@charleyer。这里有一个很好的解释:我们所做的是说每个
buchas\u id
只需要一行。选择的行基于b.buchas_id,length(t.type)desc的
顺序。这将获得最长的匹配值
buchas_type
,以防任何较短的匹配值也匹配。如果两个匹配项具有相同的长度,则拾取的匹配项是不确定的。也许我应该按b.buchas_id,length(t.type)desc,t.buchas_type_id
进行
排序,以便在出现领带的情况下,它总是返回具有最低
buchas_id
的行。我明白了。再次感谢你。