2010-05-31 26 views
27

Suponiendo que tengo una tabla que contiene la siguiente información:Combinar dos filas en SQL

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

¿hay una manera de que pueda realizar una selección en la tabla para obtener el siguiente

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

Gracias

Editar: Corregir el nombre del campo2 para mayor claridad

Respuesta

5

Hay algunas maneras que dependen de algunos datos r que no ha incluido, pero aquí hay una forma de usar lo que ha dado.

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

Otra forma:

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

podría haber un método más ordenadas, pero el siguiente podría ser uno de los enfoques:

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; 

caso de prueba:

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

Resultado:

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

Ejecución de la misma consulta sin la cláusula WHERE t.fk = 3, devolvería el siguiente conjunto de resultados:

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

Las funciones de agregación pueden ayudarle a cabo aquí. Las funciones de agregación ignoran NULLs (al menos eso es cierto en SQL Server, Oracle y Jet/Access), por lo que podría utilizar una consulta como la siguiente (probado en SQL Server Express 2008 R2):

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

Solía ​​MAX, pero cualquier agregado que elija un valor entre las filas GROUP BY debería funcionar.

datos de prueba:

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

Resultados:

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

que tenía un problema similar. La diferencia era que necesitaba mucho más control sobre lo que estaba devolviendo, así que terminé con una consulta simple pero bastante larga. Aquí hay una versión simplificada basada en su ejemplo.

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 
; 

El truco aquí es que la primera selección 'principal' selecciona las filas para mostrar. Luego tiene una selección por campo. Lo que se está uniendo debe ser todos los mismos valores devueltos por la consulta 'principal'.

Un aviso, esas otras consultas deben devolver sólo una fila por ello o que se ignoran los datos

1

si una fila tiene un valor en la columna campo1 y otras filas tienen un valor nulo, esta consulta podría funcionar.

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