2010-05-31 6 views
27

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

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

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

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

Благодарности

Редактировать: Fix field2 имя для наглядности

ответ

5

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

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 
2

Там может быть аккуратнее методы, но следующий может быть один подход:

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; 

Test Case:

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

Агрегатные функции могут помочь вам здесь. Агрегатные функции игнорировать 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 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' выбирает строки для отображения. Затем у вас есть один выбор для каждого поля. То, что объединяется, должно быть всем одним и тем же значением, возвращаемым «основным» запросом.

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

1

если одна строка имеет значение в столбце 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