我有两个结构非常相似的表.
Universidades
nombre | contenido | becas | fotos etc etc etc
Internados
nombre | todo | becas | fotos etc etc etc
Run Code Online (Sandbox Code Playgroud)
我想写一个SQL语句,它将nombre从它们中选择它们并仅在匹配时将其作为数组返回.从我所看到的UNION SELECT似乎是这样做的方式.我WHERE在最后添加了,我认为这是它出错的地方.到目前为止,我收到了第一张表的第一行.
我打错了什么?
$db = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$data = $db->prepare("SELECT nombre FROM internados UNION SELECT nombre FROM universidades WHERE nombre = ?");
$data->execute(array($nombre));
Run Code Online (Sandbox Code Playgroud)
道歉,我想从这两个表中检索一个结果.在Namees nombre列都是独立的两个表中的不同
Eri*_*ikE 20
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 = ?
;
Run Code Online (Sandbox Code Playgroud)
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
;
Run Code Online (Sandbox Code Playgroud)
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, NULLs will be placed into the columns for the other input.UNION: stacks rows vertically
UNIONUNION ALL单独(不)将删除重复的行,即使一个输入没有行请注意,UNION可以对其进行修改以完成工作,但这并不理想:
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
;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我们确保有两个值.请注意,这假设每个表中不能有两个相同的名称.如果这是真的,那么需要做更多的工作才能使UNION方法完成工作.
大部分时间union都可以通过加入来实现:
SELECT nombre
FROM internados
UNION
SELECT nombre
FROM universidades
WHERE nombre = ?
Run Code Online (Sandbox Code Playgroud)
最好是:
SELECT nombre
FROM internados i
JOIN universidades u
ON i.nombre = u.nombre
AND nombre = ?
Run Code Online (Sandbox Code Playgroud)
这更容易阅读.(您也可以使用JOIN语法,但我更喜欢普通的旧手动连接).
但无论这是a union还是a join,都要记住两个表都在结果中合并:
nombre | todo | becas | fotos | ... | contenido | becas | ...
Run Code Online (Sandbox Code Playgroud)
所以基本上,当你在nombre上放一个条件时,你要么得到一个空集,要么给你给查询的名字.但是,按照你编写联盟的方式,只有第二组才能where应用条件,而不是第一组.你应该把条件放在工会的两个查询上:
SELECT nombre
FROM internados
WHERE nombre = ?
UNION
SELECT nombre
FROM universidades
WHERE nombre = ?
Run Code Online (Sandbox Code Playgroud)