I have two tables with very similar structures.
Universidades
nombre | contenido | becas | fotos etc etc etc
Internados
nombre | todo | becas | fotos etc et
One issue to point out before we solve the problem is that each query in a UNION
is distinct and requires its own WHERE
clause. The only clause that applies to the UNION
as a whole is ORDER BY
. So your query as is needs some tweaking:
SELECT nombre
FROM dbo.internados
WHERE nombre = ? -- the added line
UNION
SELECT nombre
FROM dbo.universidades
WHERE nombre = ?
;
Second, if you want the two tables to both have the same nombre
(which is not completely clear but I'm guessing that's right), then that won't work because it simply returns one nombre
if the value is found in either table. Probably the best way to solve this is to just do a join:
SELECT I.nombre
FROM
dbo.internados I
INNER JOIN dbo.universidades U
ON I.nombre = U.nombre
WHERE
I.nombre = ?
AND U.nombre = ? -- perhaps not needed, but perhaps helpful
;
I am not 100% sure that I understand exactly what you're looking for, so please speak up if I've missed the mark.
You can think about JOIN
and UNION
this way:
JOIN
: connects rows horizontally
CROSS JOIN
) then you can get a cartesian product which is each row in one input matched to each row in the other.OUTER
join--LEFT
, RIGHT
, FULL
--if rows from the inner input (or either input with FULL
) do not match the other, NULL
s will be placed into the columns for the other input.UNION
: stacks rows vertically
UNION
by itself (not UNION ALL
) will remove duplicate rows, even if one input has no rowsNote that the UNION
could be modified to do the job, though this is not ideal:
SELECT nombre
FROM (
SELECT nombre
FROM dbo.internados
WHERE nombre = ?
UNION ALL
SELECT nombre
FROM dbo.universidades
WHERE nombre = ?
) N
GROUP BY nombre
HAVING Count(*) = 2
;
In this way we ensure there are two values. Note this assumes that there can't be two of the same name in each table. If that's true, more work would be needed to make the UNION
method do the job.
most of the time a union
can be achieved by doing a join:
SELECT nombre
FROM internados
UNION
SELECT nombre
FROM universidades
WHERE nombre = ?
would better be:
SELECT nombre
FROM internados i
JOIN universidades u
ON i.nombre = u.nombre
AND nombre = ?
which is way simpler to read. (you may also use the JOIN
syntax, but I prefer plain old manual joins).
But whether this is a union
or a join
, always remember that both tables get merged in the result:
nombre | todo | becas | fotos | ... | contenido | becas | ...
so basically, as you put a condition on nombre, you'll either get an empty set, or the name you've given to the query. But hthe way you've written your union, only the second set gets the where
condition applied, not the first one. You shall put the condition on both of the queries of the union:
SELECT nombre
FROM internados
WHERE nombre = ?
UNION
SELECT nombre
FROM universidades
WHERE nombre = ?