выберите sql-запрос для объединения результатов

#sql

#sql

Вопрос:

У меня есть таблица old_data и таблица new_data . Я хочу написать оператор select, который дает мне

  1. Строки в old_data остаются там
  2. Новые строки в new_data добавляются в old_data
  3. уникальный ключ id таков, что строки с id in new_data должны обновлять существующие в old_data

Мне нужно написать оператор select, который дал бы мне обновленные old_data с новыми данными и добавленными к ним новыми данными.

Пример:

Таблица a:

 id         count

1             2
2            19
3             4
  

Таблица b:

 id         count

2            22
5             7
  

Мне нужен оператор SELECT, который дает мне

 id         count

1             2
2            22
3             4
5             7
  

Комментарии:

1. Который RDBMS вы используете. MERGE служит для этой цели

2. Я не хочу использовать специфичную для БД конструкцию. Что-то вроде join — это то, что мне нужно

Ответ №1:

На основе желаемых результатов:

         SELECT
             *
        FROM
             [TableB] AS B
        UNION ALL
        SELECT
             *
        FROM
             [TableA] AS A
        WHERE
             A.id NOT IN (SELECT id FROM [TableB])
  

Комментарии:

1. О, нет, нет. Это не максимальная вещь. Просто обновленные данные из новой таблицы для заданного идентификатора

2. @gags ОК, изменил ответ, посмотрите этот.

3. Этот запрос выдаст мне все из таблицы B, чего не было в таблице A. Глядя на пример, он никогда не обновит строку 2 значением 22 вместо 19

4. @gags, вы должны были попробовать запустить этот код, прежде чем комментировать. вы не правы.

Ответ №2:

Я думаю, что это будет работать довольно аккуратно с COALESCE:

 SELECT a.id, COALESCE(b.count, a.count)
FROM a
FULL OUTER JOIN b
ON a.id = b.id
  

Примечание — если ваша СУБД не содержит COALESCE, вы можете записать функцию, используя РЕГИСТР следующим образом:

 SELECT a.id,
CASE WHEN b.count IS NULL THEN a.count
ELSE b.count END AS count
FROM ...
  

Вы можете написать ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ следующим образом:

 SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
UNION ALL
SELECT *
FROM b
LEFT a
ON b.id = a.id
  

Комментарии:

1. Это должно быть full outer join

2. Но он не поддерживается в Mysql OP, хочет, чтобы код работал на всех диалектах sql

3. Теперь все в порядке. COALESCE это функция ANSI SQL, которая работает во всех RDBMS , не нужно использовать CASE

Ответ №3:

Вы должны использовать UPSERT для обновления старых данных и добавления новых данных в таблицу Old_data и выбрать все строки из Old_data. Проверьте следующее и дайте мне знать, что вы думаете об этом запросе

 UPDATE [old_data]
SET [count] = B.[count]
FROM [old_data] AS A
INNER JOIN [new_Data] AS B
ON A.[id] = B.[id]

INSERT INTO [old_data]
           ([id]
           ,[count])
SELECT A.[id]
     ,A.[count]
FROM [new_Data] AS A
LEFT JOIN [old_data] AS B 
ON A.[id] = B.[id]     
WHERE B.[id] IS NULL

SELECT *
FROM [old_data]