SQL集合操作,每个集合中的列数不同

发布于 2024-11-27 09:31:33 字数 512 浏览 1 评论 0原文

假设我有集合 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 列可以在集合 2 中找到。

我的问题是基于集合的操作坚持相同数量的

我曾想过连接列内容,但我觉得这很脏。

有没有“正确”的方法来实现这一目标?

我使用的是 SQL Server 2008 R2

最后,我希望得到

1   30  60
4   30  60
5   20  40

显然我需要去睡觉,因为对 2 列的简单联接有效......谢谢!< /强>

Let say I have set 1:

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

and set 2

30  60
20  40

I would like to do some sort of union where I only keep rows 1,4,5 from set 1 because the latter 2 columns of set 1 can be found in set 2.

My problem is that set based operations insist on the same numnber of columns.

I've thought of concatenating the columns contents, but it feels dirty to me.

Is there a 'proper' way to accomplish this?

I'm on SQL Server 2008 R2

In the end, I would like to end up with

1   30  60
4   30  60
5   20  40

CLEARLY I need to go sleep as a simple join on 2 columns worked.... Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人九事 2024-12-04 09:31:33

你实际上是在要求

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

因此,如果输出仅是表 1 中的第 1、4 和 5 行,那么它是基于集合的操作,可以使用 EXISTS 或 INTERSECT 来完成或加入。对于“相同的列数”,您只需使用 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,如果您有重复项table2 中 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 将其作为“左半连接”

相交并存在于SQL Server通常给出相同的执行计划。连接类型是“左半连接”,而 INNER JOIN 是完全“等连接”。

You are literally asking for

give me the rows in t1 where the 2 columns match in T2

So if the output is only rows 1, 4 and 5 from table 1 then it is a set based operation and can be done with EXISTS or INTERSECT or JOIN. For the "same number of column", then you simply set 2 conditions with an AND. This is evaluated per row

EXISTS is the most portable and compatible way and allows any column from 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 requires the same columns in each clause and not all engines support this (SQL Server does since 2005+)

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

With an INNER JOIN, if you have duplicate values for val1, val2 in table2 then you'll get more rows than expected. The internals of this usually makes it slower then EXISTS

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

Some RBDMS support IN on multiple columns: this isn't portable and SQL Server doesn't support it

Edit: some background

Relationally, it's a semi-join (One, Two).

SQL Server does it as a "left semi join"

INTERSECT and EXISTS in SQL Server usually give the same execution plan. The join type is a "left semi join" whereas INNER JOIN is a full "equi-join".

只想待在家 2024-12-04 09:31:33

您可以使用 union ,与 union all 相反,它可以消除重复项:

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

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

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 及其下面的所有内容。

You could use union which, as opposed to union all, eliminates duplicates:

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

EDIT: Based on your edited question, you can exclude rows that match the second table using a not exists subquery:

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

If you'd like to exclude rows from table2, omit union all and everything below it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文