как выбрать две таблицы и объединить данные, чтобы не показывать дубликат

#sql #sql-server #tsql #select

#sql #sql-сервер #tsql #выберите

Вопрос:

Возможно ли достичь следующего набора результатов?

table1:

 id_s  name   post_code     city     amount1
------------------------------------------
1     name1  postal1    city1    300
2     name2  postal2    city2    400
3     name3  postal3    city3    NULL
4     name4  postal4    city4    NULL
  

таблица2:

 id_p  name   post_code     city     Amount2
------------------------------------------
1     name1  postal1    city1    300
2     name2  postal2    city2    NULL
3     name3  postal3    city3    400
5     name5  postal5    city5    500  
  

набор результатов:

 id_s  name   post_code     city     amount1  amount2
------------------------------------------
1     name1  postal1    city1    300         300
2     name2  postal2    city2    400         NULL
3     name3  postal3    city3    NULL        400
4     name4  postal4    city4    NULL        NULL
5     name5  postal5    city5    NULL        500  
  

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

1. Это простой OUTER JOIN

2. Очень странный дизайн таблицы. Почему вы храните такие похожие данные в двух отдельных таблицах? Что, если один и тот же id_p, но разные имена / города и т.д.?

3. Можем ли мы предоставить правильное решение вашей проблемы?

Ответ №1:

Попробуйте это:

     DECLARE @table1 TABLE
    ( id_s INT, name NVARCHAR(20), post_code NVARCHAR(20), 
city NVARCHAR(20), amount1 NVARCHAR(20) )
    DECLARE @table2 TABLE
    ( id_s INT, name NVARCHAR(20), post_code NVARCHAR(20), 
city NVARCHAR(20), amount2 NVARCHAR(20) )

    INSERT INTO @table1 VALUES
    ('1'     ,'name1',  'postal1',    'city1',    '300'),
    ('2'     ,'name2',  'postal2',   'city2',    '400'),
    ('3'     ,'name3',  'postal3',    'city3',    NULL),
    ('4'    ,'name4',  'postal4',    'city4',    NULL)

    INSERT INTO @table2 VALUES
    ('1',     'name1', 'postal1',    'city1',    '300'),
    ('2',     'name2',  'postal2',    'city2',    NULL),
    ('3',     'name3',  'postal3',    'city3',    '400'),
    ('5',     'name5',  'postal5',    'city5',    '500' )

    SELECT * FROM @table1

    SELECT * FROM @table2  

    SELECT 
    ISNULL(t1.id_s,t2.id_s) id_s, ISNULL(t1.name,t2.name) name,
    ISNULL(t1.post_code,t2.post_code) post_code, ISNULL(t1.city,t2.city) city,
    amount1,amount2
     FROM @table1 t1 FULL JOIN @table2 t2 ON t1.id_s = t2.id_s
  

Это даст вам идеальный результат, который вы ищете.

Надеюсь, это поможет. 🙂

Ответ №2:

A full outer join должен выполнить эту работу:

 SELECT          COALESCE(id_s, id_p),
                COALESCE(table1.name, table2.name),
                COALESCE(table1.post_code, table2.post_code),
                COALESCE(table1.city, table2.city),
                amount1,
                amount2
FROM            table1
FULL OUTER JOIN table1 ON id_s = id_p
  

Ответ №3:

Попробуйте это:

 SELECT
        COALESCE(table_1.id_s, table_2.id_p) as id
       ,COALESCE(table_1.name, table_2.name) as name
       ,COALESCE(table_1.post_code, table_2.post_code) as post_code
       ,COALESCE(table_1.city, table_2.city) as city
       ,table1.amount1
       ,table2.amount2
FROM table1
FULL OUTER JOIN table2 ON table_1.id_s = table_2.id_p
  

ВНЕШНЕЕ СОЕДИНЕНИЕ:
Ключевое слово FULL OUTER JOIN возвращает все строки из левой таблицы (table1) и все строки из правой таблицы (table2). Если в «table1» есть строки, которые не имеют совпадений в «table2», или если в «table_2» есть строки, которые не имеют совпадений в «table1», эти строки также будут перечислены.

http://www.w3schools.com/sql/sql_join_full.asp

COALESCE: вычисляет аргументы по порядку и возвращает текущее значение первого выражения, которое изначально не принимает значение NULL.

https://msdn.microsoft.com/en-us/library/ms190349.aspx