假设我已设置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个列的简单连接工作....谢谢!
答案 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不支持
编辑:一些背景
SQL Server将其作为"left semi join"
SQL Server中的INTERSECT和EXISTS通常会给出相同的执行计划。连接类型是“左半连接”,而INNER JOIN是完整的“等连接”。