SQL запрос для поиска записи в одной таблице и замены ее несколькими записями из другой таблицы - PullRequest
1 голос
/ 17 марта 2020

У меня есть две таблицы - package и subpackage as:

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);

Требуется выполнить поиск Mnemoni c 'SUB' в таблице пакетов и заменить запись SUB записями из ' Таблица «Подпакет» для сопоставленного значения Mnemoni c (153) и повторной последовательности значений последовательности, как показано в таблице [Результат] [2].

Я пытался использовать оператор обновления как:

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

Но при этом запись SUB из таблицы пакетов заменяется только записью AAA из таблицы подпакетов. Я хочу, чтобы SUB-запись была заменена всеми записями из таблицы подпакетов и повторно упорядочила ее в новой таблице, как показано в таблице Result.

Желаемый результат:

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

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Я не думаю, что вы можете обновить таблицу пакетов, чтобы получить именно тот результат, который вам нужен, т.е. проблема в том, что в вашем примере вы переупорядочиваете столбец Sequence.

В любом случае, здесь есть SQL script ( основанный на ответе 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

0 голосов
/ 18 марта 2020

Вы можете использовать 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;
...