【问题标题】:Insert record if not present for all keys in master table如果主表中的所有键都不存在,则插入记录
【发布时间】:2016-03-04 13:46:29
【问题描述】:

我有两张表,如下所述

Table1 包含键

| key  |  
| k1   |
| k2   | 
| k3   | 

表2包含键与资源的映射

  | res  |   key    |
  | r1   | k1       |
  | r1   | k2       |
  | r2   | k1       |

最终目标是在 table2 中为每个资源与每个键创建一个映射。 由于 table2 不完整,所以我需要插入不存在的映射。

那么如何找出 tale2 中缺少哪个资源 - 键映射 然后将它们插入到table2中

table2 中缺少以下键

| res| key  |  
| r1 | k3   |
| r2 | k2   | 
| r2 | k3   | 

所以最后 table2 如下所示。

  | res  |   key    |
  | r1   | k1       |
  | r1   | k2       |
  | r1   | k3       |
  | r2   | k1       |
  | r2   | k2       |
  | r2   | k3       |

任何帮助将不胜感激。

【问题讨论】:

  • 我觉得你也应该提供资源表。
  • @GiorgosBetsos 没有资源表。目标是让 table2 中的所有不同资源值都应该在 table2 本身中存在一个映射。
  • @Rishi 为什么要在最终输出中重新编号 ID?大概它们只是通过序列填充的代理主键?
  • @Boneist 不,它们不是主键。我只是在这里使用它们来显示序列。在我的真实表中,我有使用 res 列的复合键

标签: sql sql-server oracle dml


【解决方案1】:

我会质疑表中存在每个组合的必要性,因为这意味着表要么不存储相关数据(即,如果每个组合都存在,那么您可以假设并且不需要放置将其放入表中)或者有些列您没有显示,并且您将在表中放入行,这些列 NULL 作为“占位符”,这会向表中添加一堆“非数据”数据库。

无论如何,这应该可以满足您的需求:

INSERT INTO Table_2 (resource, key)
SELECT
    R.resource,
    T1.key
FROM
    Resources R
CROSS JOIN Table_1 T1
WHERE
    NOT EXISTS
    (
        SELECT *
        FROM Table_2 T2
        WHERE
            T2.resource = R.resource AND
            T2.key = T1.key
    )

【讨论】:

  • 感谢您的回复。这些是语言翻译数据库表。您可以将其视为 r1 作为资源,而 k1 、 k2 、 k3 是它在三种不同语言中的翻译。所以目前缺少不同语言的翻译,我们需要插入默认值。
【解决方案2】:

Partition outer join 加上一个空行过滤器来救援!

with t1 as (select 1 id, 'k1' key from dual union all
            select 2 id, 'k2' key from dual union all
            select 3 id, 'k3' key from dual),
     t2 as (select 1 id, 'r1' res, 'k1' key from dual union all
            select 2 id, 'r1' res, 'k2' key from dual union all
            select 3 id, 'r2' res, 'k1' key from dual)
-- end of mimicking tables t1 and t2 with your data in them. You would not need these subqueries.
-- Run the sql below, substituting in your table names as appropriate.
select t2.res,
       t1.key
from   t1
       left outer join t2 partition by (t2.res) on (t1.key = t2.key)
where  t2.id is null;

RES KEY
--- ---
r1  k3 
r2  k2 
r2  k3 

至于您添加缺失行的额外要求,它很简单:

insert into t2 (id, res, key)
select t2_seq.nextval,
       t2.res,
       t1.key
from   t1
       left outer join t2 partition by (t2.res) on (t1.key = t2.key)
where  t2.id is null;

这假设您有一个序列填充表 t2 的 id 列。

【讨论】:

    猜你喜欢
    • 2014-03-08
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 2019-07-06
    • 2021-09-03
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    相关资源
    最近更新 更多