我在连接表时遇到问题(左连接)
表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)。
答案 0 :(得分:3)
这确实是一个格式问题,最好由客户端处理。例如,在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
是一个SQL Plus命令,它可以抑制行中的重复列。它仅适用于SQL Plus客户端。正如所料,Oracle的SQL * Plus用户指南中对此进行了介绍。 Find out more.
我使用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中的行数似乎可能是可变的。
答案 1 :(得分:0)
假设您希望所有数据都在一行中,您只需要进行联合选择......
从tableA中选择fieldA 联盟 从TableB中选择fieldB
请注意,您需要将两种表的数据类型转换为相同。
如果您需要其他答案,请更好地格式化预期结果;)
好的...
你已经纠正了格式化......
在上面的例子中,我只是从我的查询返回2个游标。示例数据没有提供将两个表链接在一起的字段,因此我认为无法以合理的方式加入它们。 sproc可以返回多个结果集。
答案 2 :(得分:0)
您已完成两个表的笛卡尔积,因为您尚未指定任何连接条件。为了消除重复,您需要指定表的加入方式。
例如,您可以尝试
select * from table1, table2 where table2.val = 111;
您的示例没有任何连接键,因此加入表没有明显的价值。但这是一个更典型的例子,两个表中都会有一个相关的值,以便您可以以有意义的方式将它们连接在一起。
答案 3 :(得分:0)
你好像在这里做cross join。我怀疑你想要equi join或left outer join。