仅从多个表中选择相同的列,其中某些内容=某些内容

时间:2013-06-13 16:49:10

标签: sql

我有两张结构非常相似的桌子。

Universidades
nombre | contenido | becas | fotos etc etc etc
Internados
nombre | todo | becas | fotos etc etc etc

我想编写一个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));

道歉,我想从这两个表中检索一个结果。 nombre列中的名称在两个表中都是个体和不同的

2 个答案:

答案 0 :(得分:20)

在我们解决问题之前要指出的一个问题是UNION中的每个查询都是不同的,并且需要自己的WHERE子句。适用于UNION整体的唯一条款是ORDER BY。所以你的查询需要一些调整:

SELECT nombre
FROM dbo.internados
WHERE nombre = ? -- the added line
UNION
SELECT nombre
FROM dbo.universidades
WHERE nombre = ?
;

其次,如果你想要两个表都具有相同的nombre(这不是很清楚,但我猜是正确的),那么这将无法工作,因为它只返回一个{{1如果在 表中找到该值。解决这个问题的最佳方法可能就是加入:

nombre

我并不是100%确定我完全理解你在寻找什么,所以如果我错过了标记,请说出来。

您可以这样考虑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 ; JOIN

  • UNION :水平连接行
    • 符合条件
    • 创建新的
    • 不完全创建行,因为所有数据都来自现有行,但当条件匹配另一个输入中的多行时,从一个输入复制一行。如果两个输入都有重复,那么它会将一个输入的行数乘以另一个输入的匹配行数。
    • 如果根本没有匹配条件(想想JOIN),那么你可以得到一个笛卡尔积,它是一个输入中的每一行与另一行中的每一行匹配。
    • 使用CROSS JOIN加入时,OUTERLEFTRIGHT - 来自内部输入的行(或使用FULL输入的行)与其他输入不匹配,FULL将被放入另一个输入的列中。
  • NULL :垂直堆叠行
    • 通常,创建新的
    • 没有使用条件,没有真正的匹配
    • UNION本身(不是UNION)将删除重复的行,即使一个输入没有行

请注意,可以修改UNION 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 ; 方法完成工作。

答案 1 :(得分:5)

大多数情况下,通过加入可以实现union

SELECT nombre 
  FROM internados 
UNION 
SELECT nombre 
  FROM universidades 
 WHERE nombre = ?

最好是:

SELECT nombre
  FROM internados i
  JOIN universidades u
    ON i.nombre = u.nombre
   AND nombre = ?

这样更容易阅读。 (您也可以使用JOIN语法,但我更喜欢普通的旧手动连接。

但无论这是union还是join,请始终记住两个表都会在结果中合并:

nombre | todo | becas | fotos | ... | contenido | becas | ...

所以基本上,当你在nombre上设置一个条件时,你要么得到一个空集,要么给你给查询的名字。但是,按照你编写联合的方式,只有第二组应用了where条件,而不是第一组。你应该把条件放在工会的两个问题上:

SELECT nombre 
  FROM internados 
 WHERE nombre = ?
UNION 
SELECT nombre 
  FROM universidades 
 WHERE nombre = ?