SQL集操作在每个集合中具有不同数量的列

时间:2011-08-01 07:23:05

标签: sql-server set

假设我已设置1:

1   30  60
2   45  90
3   120 240
4   30  60
5   20  40

并设置2

30  60
20  40

我想做某种联合,我只保留第1组中的第1,4,5行,因为第1组的后两列可以在第2组中找到。

我的问题是基于设置的操作坚持使用的同一个numnber。

我想过连接列内容,但对我来说感觉很脏。

是否有'正确'的方法来实现这一目标?

我在使用SQL Server 2008 R2

最后,我想以

结束
1   30  60
4   30  60
5   20  40

清楚我需要睡觉,因为2个列的简单连接工作....谢谢!

2 个答案:

答案 0 :(得分:1)

你可以使用union而不是union all来消除重复:

select  val1, val2
from    table1
union
select  val1, val2
from    table1

编辑:根据您编辑的问题,您可以使用not exists子查询排除与第二个表匹配的行:

select  id, col1, col2
from    table1 t1
where   not exists
        (
        select  *
        from    table2 t2
        where   t1.col1 = t2.col1
                and t1.col2 = t2.col2
        )
union all
select  null, col1, col2
from    table2

如果您要排除table2中的行,请忽略union all及其下方的所有内容。

答案 1 :(得分:1)

你真的要求

  

给我t1中的行,其中2列在T2中匹配

因此,如果输出只是表1中的第1,4和5行,则 是基于集合的操作,可以使用EXISTS或INTERSECT或JOIN完成。对于“相同的列数”,您只需使用AND设置2个条件。这是每行评估的

EXISTS是最便携和兼容的方式,允许来自table1的任何列

select  id, val1, val2
from    table1 t1
WHERE EXISTS (SELECT * FROM table2 t2
                  WHERE t1.val1 = t2.val1 AND t1.val2 = t2.val2)

INTERSECT在每个子句中都需要相同的列,而且并非所有引擎都支持这一点(SQL Server自2005年开始执行此操作)

select  val1, val2
from    table1
INTERSECT
select  val1, val2
from    table2

使用INNER JOIN,如果表2中的val1, val2有重复值,那么您将获得比预期更多的行。这种内部结构通常会比EXISTS慢。

select  t1.id, t1.val1, t1.val2
from    table1 t1
        JOIN
        table2 t2 ON t1.val1 = t2.val1 AND t1.val2 = t2.val2

某些RBDMS支持多列上的IN:这不可移植,SQL Server不支持

编辑:一些背景

相关地,它是半连接(OneTwo)。

SQL Server将其作为"left semi join"

SQL Server中的INTERSECT和EXISTS通常会给出相同的执行计划。连接类型是“左半连接”,而INNER JOIN是完整的“等连接”。