Подтвердить что ты не робот

Слияние двух строк в SQL

Предполагая, что у меня есть таблица, содержащая следующую информацию:

FK | Field1 | Field2
=====================
3  | ABC    | *NULL*
3  | *NULL* | DEF

есть способ, которым я могу выполнить выбор в таблице, чтобы получить следующий

FK | Field1 | Field2
=====================
3  | ABC    | DEF

Спасибо

Изменить: исправить имя поля2 для ясности

4b9b3361

Ответ 1

Агрегатные функции могут помочь вам здесь. Совокупные функции игнорируют NULLs (по крайней мере, это верно для SQL Server, Oracle и Jet/Access), поэтому вы можете использовать такой запрос (проверенный на SQL Server Express 2008 R2):

SELECT
    FK,
    MAX(Field1) AS Field1,
    MAX(Field2) AS Field2
FROM
    table1
GROUP BY
    FK;

Я использовал MAX, но любой агрегат, который выбирает одно значение из строк GROUP BY, должен работать.

Данные теста:

CREATE TABLE table1 (FK int, Field1 varchar(10), Field2 varchar(10));

INSERT INTO table1 VALUES (3, 'ABC', NULL);
INSERT INTO table1 VALUES (3, NULL, 'DEF');
INSERT INTO table1 VALUES (4, 'GHI', NULL);
INSERT INTO table1 VALUES (4, 'JKL', 'MNO');
INSERT INTO table1 VALUES (4, NULL, 'PQR');

Результаты:

FK  Field1  Field2
--  ------  ------
3   ABC     DEF
4   JKL     PQR

Ответ 2

Есть несколько способов в зависимости от некоторых правил данных, которые вы не включили, но вот один из способов использования того, что вы дали.

SELECT
    t1.Field1,
    t2.Field2
FROM Table1 t1
    LEFT JOIN Table1 t2 ON t1.FK = t2.FK AND t2.Field1 IS NULL

Другой способ:

SELECT
    t1.Field1,
    (SELECT Field2 FROM Table2 t2 WHERE t2.FK = t1.FK AND Field1 IS NULL) AS Field2
FROM Table1 t1

Ответ 3

У меня была аналогичная проблема. Разница заключалась в том, что мне нужно было гораздо больше контролировать то, что я возвращаю, поэтому у меня появился простой, но довольно длинный запрос. Вот упрощенная версия, основанная на вашем примере.

select main.id, Field1_Q.Field1, Field2_Q.Field2
from 
(
    select distinct id
    from Table1
)as main
left outer join (
    select id, max(Field1)
    from Table1
    where Field1 is not null
    group by id
) as Field1_Q on main.id = Field1_Q.id
left outer join (
    select id, max(Field2)
    from Table1
    where Field2 is not null
    group by id
) as Field2_Q on main.id = Field2_Q.id 
;

Трюк здесь в том, что первый select 'main' выбирает строки для отображения. Затем у вас есть один выбор для каждого поля. То, что соединяется, должно быть всех значений, возвращаемых "основным" запросом.

Будьте осторожны, эти другие запросы должны возвращать только одну строку на один идентификатор или вы будете игнорировать данные

Ответ 4

Могут быть более простые методы, но следующим может быть один подход:

SELECT    t.fk,
          (
             SELECT t1.Field1 
             FROM   `table` t1 
             WHERE  t1.fk = t.fk AND t1.Field1 IS NOT NULL
             LIMIT  1
          ) Field1,
          (
             SELECT t2.Field2
             FROM   `table` t2 
             WHERE  t2.fk = t.fk AND t2.Field2 IS NOT NULL
             LIMIT  1
          ) Field2
FROM      `table` t
WHERE     t.fk = 3
GROUP BY  t.fk;

Тестовый пример:

CREATE TABLE `table` (fk int, Field1 varchar(10), Field2 varchar(10));

INSERT INTO `table` VALUES (3, 'ABC', NULL);
INSERT INTO `table` VALUES (3, NULL, 'DEF');
INSERT INTO `table` VALUES (4, 'GHI', NULL);
INSERT INTO `table` VALUES (4, NULL, 'JKL');
INSERT INTO `table` VALUES (5, NULL, 'MNO');

Результат:

+------+--------+--------+
| fk   | Field1 | Field2 |
+------+--------+--------+
|    3 | ABC    | DEF    |
+------+--------+--------+
1 row in set (0.01 sec)

Запустив тот же запрос без предложения WHERE t.fk = 3, он вернет следующий набор результатов:

+------+--------+--------+
| fk   | Field1 | Field2 |
+------+--------+--------+
|    3 | ABC    | DEF    |
|    4 | GHI    | JKL    |
|    5 | NULL   | MNO    |
+------+--------+--------+
3 rows in set (0.01 sec)

Ответ 5

, если одна строка имеет значение в столбце field1, а другие строки имеют нулевое значение, то этот запрос может работать.

SELECT
  FK,
  MAX(Field1) as Field1,
  MAX(Field2) as Field2
FROM 
(
select FK,ISNULL(Field1,'') as Field1,ISNULL(Field2,'') as Field2 from table1
)
tbl
GROUP BY FK

Ответ 6

В моем случае у меня есть такая таблица

---------------------------------------------
|company_name|company_ID|CA        |   WA   |
---------------------------------------------
|Costco      |   1      |NULL      | 2      |
---------------------------------------------
|Costco      |   1      |3         |Null    |
---------------------------------------------

И я хочу, чтобы это было так:

---------------------------------------------
|company_name|company_ID|CA        |   WA   |
---------------------------------------------
|Costco      |   1      |3         | 2      |
---------------------------------------------

Большая часть кода практически одинакова:

SELECT
    FK,
    MAX(CA) AS CA,
    MAX(WA) AS WA
FROM
    table1
GROUP BY company_name,company_ID

Единственное отличие - это group by, если вы поместите в него два имени столбца, вы можете сгруппировать их попарно.