繁体   English   中英

SQL 查询在一个表中搜索记录并将其替换为另一个表中的多条记录

[英]SQL query to search for a record in one table and replace it with multiple records from another table

我有两个表 - 包和子包为:

CREATE TABLE Package (
    Sequence int PRIMARY KEY,
    Package int,
    Mnemonic char(3),
    MnemonicValue int
);

CREATE TABLE SubPackage (
    Sequence int PRIMARY KEY,
    SubPackage int,
    Mnemonic char(3),
    MnemonicValue int
);

INSERT INTO Package (Sequence, Package, Mnemonic, MnemonicValue)
VALUES (1, 111, 'XXX', 0), (2, 111, 'SUB', 153), (3, 111, 'DDD', 30), (4, 111, 'YYY', 20), (5, 111, 'ZZZ', 1000);

INSERT INTO SubPackage (Sequence, SubPackage, Mnemonic, MnemonicValue)
VALUES (1, 153, 'AAA', 20), (2, 153, 'BBB', 1000), (3, 153, 'CCC', 30);

要求是在包表中搜索助记符 'SUB' 并将 SUB 记录替换为映射助记符值 (153) 的 'Subpackage' 表中的记录,并对序列值重新排序,如 [Result][2] ] 桌子。

我曾尝试将更新语句用作:

UPDATE package
SET    Mnemonic = subpackage.Mnemonic
FROM   package
       INNER JOIN subpackage
       ON package.MnemonicValue = subpackage.SubPackage

但这只是用子包表中的 AAA 记录替换了包表中的 SUB 记录。 我希望将 SUB 记录替换为子包表中的所有记录,并在新表中对其重新排序,如结果表中所示。

想要的结果:

Sequence | Particular | Mnemonic | MnemonicValue

       1 |         111|       XXX|             0        
       2 |         111|       AAA|            20
       3 |         111|       BBB|          1000
       4 |         111|       CCC|            30
       5 |         111|       DDD|            30
       6 |         111|       YYY|            20
       7 |         111|       ZZZ|          1000

您可以使用left join来获得您想要的结果:

select
    p.sequence,
    p.package,
    coalesce(s.mnemonic, p.mnemonic) mnemonic,
    coalesce(s.mnemonic_value, p.mnemonic_value) mnemonic_value
from package p
left join sub_package s 
    on  p.mnemonic = 'SUB'
    and p.mnemonic_value = s.sub_package

“替换”新行有点复杂。 插入新行然后删除原始行可能会更简单(您可以在事务中执行此操作):

start transaction;

insert into package(sequence, package, mnemonic, mnemonic_value)
select
    p.sequence,
    p.package,
    coalesce(s.mnemonic, p.mnemonic),
    coalesce(s.mnemonic_value, p.mnemonic_value)
from package p
left join sub_package s 
    on  p.mnemonic = 'SUB'
    and p.mnemonic_value = s.sub_package;

delete from package where mnemonic = 'SUB';

commit;

我认为您无法更新 Package 表以获得您想要的确切结果,即问题是在您的示例中您重新排序了Sequence列。

无论如何,这里是 SQL 脚本(基于 GMB 的回答),它将生成您想要获得的结果:

select
    ROW_NUMBER() OVER (ORDER BY p.Sequence) as Sequence,
    p.Package,
    coalesce(s.Mnemonic, p.Mnemonic) Mnemonic,
    coalesce(s.MnemonicValue, p.MnemonicValue) MnemonicValue
from Package p
left join SubPackage s 
    on p.MnemonicValue = s.SubPackage
order by p.Sequence

但是,AFAIK 它仅适用于 MySQL 8

这是SQLFiddle链接,但要注意它是用于 Postgres 的(因为 SQLFiddle 不支持 MySQL 8)。

如果您使用的是较早版本的 MySQL,您可以尝试模拟 row_number 函数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM