【问题标题】:Problem with joining db tables连接数据库表的问题
【发布时间】:2009-09-22 13:06:19
【问题描述】:

加入表格时遇到问题(左联接)

表1:

id1  amt1
1    100
2    200
3    300

表2:

id2  amt2
1    150
2    250
2    350

我的查询:

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

我希望第 3 行中的 o/p 为

2 null 2 350

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

【问题讨论】:

  • 真的没有给我们太多的工作。这两个表中是否只有一列?还是 table1 有 4 列而 table2 有 2 列?也许你可以给我们一个确切的例子,说明你希望结果是什么样的?
  • 你想得到什么结果(我不清楚)?两张表有什么关系(是否有外键)?
  • 为什么结果集中没有table1.id1 = 3的一行?

标签: sql oracle plsql oracle9i


【解决方案1】:

这确实是一个格式问题,最好由客户端处理。例如,在 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>

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

编辑

BREAK 是一个 SQLPlus 命令,用于抑制行中的重复列。它仅适用于 SQLPlus 客户端。正如所料,它在 Oracle 的 SQL*Plus 用户指南中有所介绍。 Find out more.

我以BREAK 为例说明了正确的做事方式,因为它很干净并且正确地实现了关注点分离。如果您使用的是不同的客户端,则需要使用 its 格式化功能。可以调整 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 中的行数似乎是可变的。

【讨论】:

  • 我的问题已更改,请看一下你回答我的问题,我正在使用 oracle 9i
  • 我仍然认为通过在客户端应用格式而不是弄乱 SQL 会更好地满足您的要求。
【解决方案2】:

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

从表 A 中选择字段 A 联盟 从表B中选择字段B

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

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

好的...

您已更正格式...

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

【讨论】:

    【解决方案3】:

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

    例如,你可以试试

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

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

    【讨论】:

    • 只有1行数据,会过滤掉空的222行
    【解决方案4】:

    你似乎在这里做一个cross join。我怀疑你想要equi joinleft outer join

    【讨论】:

      猜你喜欢
      • 2020-04-06
      • 1970-01-01
      • 2016-07-12
      • 2012-02-29
      • 2011-05-19
      • 2017-03-21
      相关资源
      最近更新 更多