基于匹配列进行选择

4
我有两个表,都包含各种公司。我想从tableTwo中选择所有在tableOne中出现的内容(实际上,仅当它在tableTwo中出现时)。我将通过比较它们的companyID字段来实现此目的。它们还必须具有列someYear的相同值。换句话说,如果且仅如果它们的someYear列匹配,我想从tableOne返回出现在tableTwo中的公司。
tableOne

companyID    someYear
---------    --------
1            2010
2            2009
3            2011
1            2011
7            2009


tableTwo

companyID    someYear
---------    --------
1            2010
2            2008
3            2011
4            2011
5            2009

我希望返回13(由于公司2的年份不同,所以我不需要它)。我的无用尝试:

SELECT one.* 
FROM tableOne one, tableTwo two
WHERE one.[companyID] in (
  SELECT DISTINCT companyID
  FROM tableTwo
)
and one.someYear = two.someYear;

问题在于,这个查询返回了数百万行结果,而这两个表中的条目数量都不到1万。由于信息敏感,我无法准确重现输出。正如你所看到的,这里的表/列名都是虚构的。另外,我应该指出这两个表似乎都没有主键。我认为这会导致它们无法进行匹配。我正在使用SQL Server 2008。任何帮助将不胜感激。

2个回答

12

试试这个

select one.*
from tableOne as one
  inner join tableTwo as two
    on one.companyID = two.companyID and
       one.someYear = two.someYear

@Lamak 我在任何涉及到 join 的事情上都异常糟糕,我真的应该好好学习它们。我只有一个简单的跟进问题。这个查询返回的行数比 tableTwo 中的行数还要多,这让我很意外。看一些返回的行,我可以看到一些重复的数据。显然,我可以使用 DISTINCT 删除重复项。不过我想知道为什么会出现这些重复项?因为它们在任何一个表中都没有重复。例如,有一家公司在 tableTwo 中有两行记录,但是这个查询返回了三行 - 其中有两行是相同/重复的。 - Ciarán Tobin
2
@MadScone - 如果在tabelOne中有重复的行,并且在tableTwo中有与该重复行匹配的一行,则结果集中将为每个tableOne中的行返回一行。 - Mikael Eriksson

4

INNER JOIN 不是执行半连接的唯一方式。以下是另一种同样有效的方法:

SELECT * 
  FROM tableOne one
 WHERE EXISTS (
               SELECT *
                 FROM tableTwo two
                WHERE one.companyID = two.companyID
                      AND one.someYear = two.someYear
              );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接