连接数据库表时出现问题

发布于 2024-08-05 08:20:03 字数 541 浏览 5 评论 0原文

我在连接表(左连接)时遇到问题

table1:

id1  amt1
1    100
2    200
3    300

table2:

id2  amt2
1    150
2    250
2    350

my Query:

select id1,amt1,id2,amt2 from table1
left join table2 on table2.id1=table1.id2

我假设的 o/p 是:

      id1 amt1  id2 amt2
row1: 1   100   1    150
row2: 2   200   2    250
row3: 2   200   2    350

我想要 row3 中的 o/p,因为

2 null 2 350

我想避免重复数据(amt1)。

I have problem when joining tables (left join)

table1:

id1  amt1
1    100
2    200
3    300

table2:

id2  amt2
1    150
2    250
2    350

my Query:

select id1,amt1,id2,amt2 from table1
left join table2 on table2.id1=table1.id2

My supposed o/p is:

      id1 amt1  id2 amt2
row1: 1   100   1    150
row2: 2   200   2    250
row3: 2   200   2    350

I want o/p in row3 as

2 null 2 350

ie I want avoid repetition of data(amt1).

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

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

发布评论

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

评论(4

深海里的那抹蓝 2024-08-12 08:20:03

这确实是一个格式问题,最好由客户端来处理。例如,在 SQL*Plus 中,我们可以使用 BREAK ....

SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
aaa bbb ccc ddd        222

SQL> break on a on b on c on d
SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
                       222

SQL>

注意:在没有任何进一步信息的情况下,我选择了笛卡尔积。

edit

BREAK 是一个 SQLPlus 命令,它可以抑制行中的重复列。它仅适用于 SQLPlus 客户端。正如所料,Oracle 的 SQL*Plus 用户指南中对此进行了介绍。 了解更多信息。

我使用 BREAK 作为正确处理方式的示例,因为它很干净并且正确实现了关注点分离。如果您使用不同的客户端,则需要使用其格式化功能。可以调整 SQL(见下文),但这会降低查询的实用性,因为我们无法在不想抑制重复值的其他地方重用该查询。

无论如何,这是一种在内联视图中使用 ROW_NUMBER() 分析函数的解决方案。

SQL> select * from t1
  2  /

A   B   C   D           ID
--- --- --- --- ----------
eee fff ggg hhh          1
aaa bbb ccc ddd          2

SQL> select * from t2
  2  /

        C1         ID
---------- ----------
       333          2
       111          1
       222          2
       444          2

SQL> select t1_id
  2         , case when rn = 1 then a else null end as a
  3         , t2_id
  4         , c1
  5  from (
  6      select t1.id as t1_id
  7             , row_number () over (partition by t1.id order by t2.c1) as rn
  8             , t1.a
  9             , t2.c1
 10             , t2.id as t2_id
 11      from t1, t2
 12      where t1.id = t2.id
 13      )
 14  order by t1_id, rn
 15  /

     T1_ID A        T2_ID         C1
---------- --- ---------- ----------
         1 eee          1        111
         2 aaa          2        222
         2              2        333
         2              2        444

SQL>

我选择不使用 LAG(),因为它仅适用于固定偏移量,而且 T2 中的行数似乎是可变的。

This really is a formatting issue which is best handled by the client. For instance, in SQL*Plus we can use BREAK ....

SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
aaa bbb ccc ddd        222

SQL> break on a on b on c on d
SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
                       222

SQL>

Note: in the absence of any further information I opted for a Cartesian product.

edit

BREAK is a SQLPlus command, which suppresses duplicate columns in our rows. It only works in the SQLPlus client. As might be expected, it is covered in Oracle's SQL*Plus User Guide. Find out more.

I used BREAK as an example of the proper way of doing things, because it is clean and correctly implements the separation of concerns. It you are using a different client you would need to use its formatting capabilities. It is possible to tweak the SQL (see below) but that diminishes the utility of the query, because we cannot reuse the query in other places which don't want to suppress the duplicated values.

Anyway, here is one solution which uses the ROW_NUMBER() analytic function in an inline view.

SQL> select * from t1
  2  /

A   B   C   D           ID
--- --- --- --- ----------
eee fff ggg hhh          1
aaa bbb ccc ddd          2

SQL> select * from t2
  2  /

        C1         ID
---------- ----------
       333          2
       111          1
       222          2
       444          2

SQL> select t1_id
  2         , case when rn = 1 then a else null end as a
  3         , t2_id
  4         , c1
  5  from (
  6      select t1.id as t1_id
  7             , row_number () over (partition by t1.id order by t2.c1) as rn
  8             , t1.a
  9             , t2.c1
 10             , t2.id as t2_id
 11      from t1, t2
 12      where t1.id = t2.id
 13      )
 14  order by t1_id, rn
 15  /

     T1_ID A        T2_ID         C1
---------- --- ---------- ----------
         1 eee          1        111
         2 aaa          2        222
         2              2        333
         2              2        444

SQL>

I chose not to use LAG(), because that only works with fixed offsets, and it seemed likely that the number of rows in T2 would be variable.

千仐 2024-08-12 08:20:03

假设您希望所有数据都在一行中,您只需执行联合选择...

Select fieldA from tableA
联盟
Select fieldB from TableB

请注意,您需要将两个表的数据类型转换为相同。

如果您需要其他答案,请更好地格式化预期结果;)

好的...

您已经更正了格式...

在上面的情况下,我只会从查询中返回 2 个游标。示例数据没有提供将两个表链接在一起的字段,因此我认为无法以合理的方式将它们连接起来。一个存储过程可以返回多个结果集。

Assuning you want all data in a single row, you just do a union select...

Select fieldA from tableA
Union
Select fieldB from TableB

Note that you need to cast the datatype to be the same for both tables.

If you need an other answer, please format the expected result better ;)

Ok...

You have corrected the formating...

In the case above I would simply return 2 cursors from my query. The example data provides no field to link both tables together, so i see no way to join them in a resonable manner. It is possible for a sproc to return several resultsets.

眼趣 2024-08-12 08:20:03

由于您没有指定任何连接条件,因此您已经完成了两个表的笛卡尔积。为了消除重复,您需要指定表的连接方式。

例如,您可以尝试

select * from table1, table2 where table2.val = 111;

您的示例没有任何连接键,因此没有明显的值可以连接表。但有一个更典型的示例,两个表中都会有一个相关值,以便您可以以有意义的方式将它们连接在一起。

You've done the cartesian product of the two tables since you haven't specified any join criteria. In order to eliminate duplicates, you need to specify how you want the tables to join.

For example, you could try

select * from table1, table2 where table2.val = 111;

Your example doesn't have any join key, so there's no obvious value to join the tables on. But is a more typical example, there would be a related value in both tables so that you could join them together in a meaningful way.

等数载,海棠开 2024-08-12 08:20:03

您似乎在此处进行交叉联接。我怀疑您想要 equi join左外连接

You seem to be doing a cross join here. I suspect you wanted either an equi join or a left outer join.

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