将一个表中的值分配给另一表

时间:2019-02-07 09:55:01

标签: sql postgresql sql-update dml

有两个表,表A和表B。它们包含相同的列cost和item。表B包含项目清单及其相应的成本,而表A仅包含项目清单。

现在我们需要检查表A的项目,如果它们存在于表B中,则应将相应的项目成本分配给表A中的项目成本。

有人可以通过为此查询来帮助我。

考虑如下表:

表A:

item    cost
------------- 
pen     null
book    null
watch   null

表B:

item     cost
------------- 
watch    1000
book     50

预期产量

Table A:

item    cost
pen       0
book     50
watch   1000

3 个答案:

答案 0 :(得分:0)

只需在表B中添加外键(表A的主键),就可以说表A ID,然后在查询中添加联接(可能是右联接)以获取或分配各自的价格项目。

join就像

SELECT item, cost
    FROM tablename a
    RIGHT JOIN tablename b ON a.item= b.item;

编辑:

只需编辑该表名,现在运行它即可。

答案 1 :(得分:0)

有很多方法可以执行此操作,如果您将表b用作包含价格的表,那么左外部联接将解决问题。

SELECT
    table_a.item,
    CASE
        WHEN table_b.cost IS NULL
        THEN 0
        ELSE table_b.cost
    END as cost
FROM table_a
LEFT OUTER JOIN table_b ON table_a.item = table_b.item

该结果似乎还表明,不在表b中的笔的价格应为0(这是不正确的做法),但是为了返回所需的结果,您需要case语句分配一个值,如果它为空。

根据评论更新表格

update table_a set cost = some_alias.cost
from (
    SELECT
        table_a.item,
        CASE
        WHEN table_b.cost IS NULL
        THEN 0
        ELSE table_b.cost
        END as cost
    FROM table_a
    LEFT OUTER JOIN table_b ON table_a.item = table_b.item
) some_alias
where table_a.item = some_alias.item

答案 2 :(得分:0)

我会这样构造更新:

with cost_data as (
  select
    item,
    max (cost) filter (where item = 'watch') as watch,
    max (cost) filter (where item = 'book') as book
  from table_b
  group by item
)
update table_a a
set
  watch = c.watch,
  book = c.book
from cost_data c
where
  a.item = c.item and
 (a.watch is distinct from c.watch or
  a.book is distinct from c.book)

从本质上讲,我正在执行一个常见的表表达式以在表B上创建一个穷人数据透视表,以将行划分为列。需要注意的是-如果同一项目列出了多个成本,则可能无法满足您的要求,但是您几乎需要在任何情况下都知道如何处理。

然后我针对CTE执行“从B更新A”。

最后一部分本身并不重要,但是很有用-将查询限制为仅在需要更改的行上执行。如果不需要DML,最好限制DML(优化某些内容的最佳方法是不这样做)。