sql - una - relacion uno a varios ejemplos
Seleccione el primer registro en una relaciĆ³n uno a varios utilizando la combinaciĆ³n izquierda (7)
Estoy tratando de unir dos tablas utilizando una combinación a la izquierda. Y el conjunto de resultados debe incluir solo el primer registro de la tabla "derecha" unida.
Digamos que tengo dos tablas A y B como abajo;
Tabla "A"
code | emp_no
101 | 12222
102 | 23333
103 | 34444
104 | 45555
105 | 56666
Tabla "b"
code | city | county
101 | Glen Oaks | Queens
101 | Astoria | Queens
101 | Flushing | Queens
102 | Ridgewood | Brooklyn
103 | Bayside | New York
Rendimiento esperado:
code | emp_no | city | county
101 | 12222 | Glen Oaks | Queens
102 | 23333 | Ridgewood | Brooklyn
103 | 34444 | Bayside | New York
104 | 45555 | NULL | NULL
105 | 56666 | NULL | NULL
Si nota que mi resultado solo tiene un registro coincidente de la tabla "B" (no importa qué registro coincida) después de la combinación izquierda (y es un mapeo de uno a muchos)
Necesito elegir el primer registro coincidente de la tabla B e ignorar todas las demás filas.
¡Por favor ayuda!
Gracias
Otra opción: OUTER APPLY
Si la base de datos lo admite, OUTER APPLY
es una opción eficiente y concisa.
SELECT *
FROM
Table_A a
OUTER APPLY
(SELECT TOP 1 *
FROM Table_B b_1
WHERE b_1.code = a.code
) b
;
Esto da como resultado una unión izquierda al primer registro indeterminado coincidente. Mis pruebas muestran que es más rápido que cualquier otra solución publicada (en MS SQL Server 2012).
Después de jugar un poco, ¡esto resulta ser más complicado de lo que esperaba! Suponiendo que table_b
tiene alguna columna única que es única (por ejemplo, una clave principal de un solo campo), parece que puede hacer esto:
SELECT table_a.code,
table_a.emp_no,
table_b.city,
table_b.county
FROM table_a
LEFT
JOIN table_b
ON table_b.code = table_a.code
AND table_b.field_that_is_unique =
( SELECT TOP 1
field_that_is_unique
FROM table_b
WHERE table_b.code = table_a.code
)
;
En Oracle puedes hacer:
WITH first_b AS (SELECT code, min(rowid) AS rid FROM b GROUP BY code))
SELECT a.code, a.emp_no, b.city, b.county
FROM a
INNER JOIN first_b
ON first_b.code = a.code
INNER JOIN b
ON b.rowid = first_b.rid
La respuesta más votada no me parece correcta y parece demasiado complicada. Solo agrupe por el campo de código en la tabla B en su subconsulta y seleccione la ID máxima por agrupación.
SELECT
table_a.code,
table_a.emp_no,
table_b.city,
table_b.county
FROM
table_a
LEFT JOIN
table_b
ON table_b.code = table_a.code
AND table_b.field_that_is_unique IN
(SELECT MAX(field_that_is_unique)
FROM table_b
GROUP BY table_b.code)
Modifiqué la respuesta de ruakh y esto parece funcionar perfectamente con mysql.
SELECT
table_a.code,
table_a.emp_no,
table_b.city,
table_b.county
FROM table_a a
LEFT JOIN table_b b
ON b.code = a.code
AND b.id = ( SELECT id FROM table_b
WHERE table_b.code = table_a.code
LIMIT 1
)
;
Si está en SQL Server 2005 o una versión posterior, puede usar la ranking para lograr lo que desea. En particular, ROW_NUMBER()
parece satisfacer tus necesidades muy bien:
WITH B_ranked AS (
SELECT
*,
rnk = ROW_NUMBER() OVER (PARTITION BY code ORDER BY city)
FROM B
)
SELECT
A.code,
A.emp_no,
B.city,
B.county
FROM A
LEFT JOIN B_ranked AS B ON A.code = B.code AND b.rnk = 1
O
WITH B_unique_code AS (
select * from(
SELECT
*,
rnk = ROW_NUMBER() OVER (PARTITION BY code ORDER BY city)
FROM B
) AS s
where rnk = 1
)
SELECT
A.code,
A.emp_no,
B.city,
B.county
FROM A
LEFT JOIN B_unique_code AS B ON A.code = B.code
así es como:
Select * From TableA a
Left Join TableB b
On b.Code = a.Code
And [Here put criteria predicate that ''defines'' what the first record is]
Oye, si la ciudad y el condado son únicos, entonces úsalos
Select * From TableA a
Left Join TableB b
On b.Code = a.Code
And b.City + b.county =
(Select Min(city + county)
From TableB
Where Code = b.Code)
Pero el punto es que hay que poner alguna expresión allí para decirle al procesador de consultas qué significa ser primero .