【问题标题】:Update all fields in a column from subquery postgresql从子查询 postgresql 更新列中的所有字段
【发布时间】:2020-07-17 15:07:35
【问题描述】:

我有一张桌子,比如buchas,其中包含产品列表。我必须创建另一个表buchas_type,其中包含buchas 中产品的类型(如果您愿意,可以使用类)。

现在我必须通过添加type_id 列来引用buchas 中的产品类别。

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

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

   -----------------Name----------------- | ---Type---
               BUCHA GOB 1600                   GOB

问题是我有一个类型 GOB(2) 会与类型 GOB 混淆。 (我也有其他相似的类型提出了同样的问题)。

到目前为止,我得到了这个:

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_type_id。例如,如果我尝试Where buchas.id = 50,我会得到正确的结果。

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

如何实现?

【问题讨论】:

    标签: postgresql sql-update subquery


    【解决方案1】:

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

    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)
    

    解决了这个问题,你可以做一个update...from

    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 语句是如何解决类型相似问题的。你介意解释一下吗?非常感谢您的帮助。
    • @CharleyR。这是一个很好的解释:stackoverflow.com/a/9795768/13808319 我们所做的是说我们只希望每个buchas_id 有一行。选择的行基于order by b.buchas_id, length(t.type) desc。这为我们提供了最长的匹配buchas_type,以防任何较短的匹配也匹配。如果两个匹配具有相同的长度,则被选中的匹配是不确定的。也许我应该输入order by b.buchas_id, length(t.type) desc, t.buchas_type_id,以便在出现平局时它总是返回buchas_type_id 最低的行。
    • 我明白了。再次感谢您。
    猜你喜欢
    • 2021-01-19
    • 2013-07-09
    • 2011-11-19
    • 2019-01-27
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    相关资源
    最近更新 更多