从具有不同字段和唯一值的两个表中获取值

时间:2015-10-25 11:14:52

标签: php mysql sql

我有两个表app_test1和app_test2  在app_test1中         

billdt       tracknum   ups_netchg
10/25/2015   221        455
10/25/2015   222        245
10/25/2015   223        123
10/25/2015   224        888

表2中的

app_test2

billdt       tracknum   optic_netchg
10/25/2015   221        456
10/25/2015   222        890
10/25/2015   223        345
10/25/2015   226        987

现在我想要这样。

billdt       tracknum   ups_netchg  optic_netchg
10/25/2015   221        455         456
10/25/2015   222        245         890
10/25/2015   223        123         345
10/25/2015   224        888         NULL
10/25/2015   226        NULL        987

我的代码是这样的:

select test.billdt,test.tracknum,

IfNull(app_test1.ups_netchg,0) as ups_netchg,
IfNull(app_test2.optics_netchg,0) as optics_netchg

from (
select app_test1.tracknum, app_test1.billdt

from app_test1 union

select app_test2.tracknum, app_test2.billdt from app_test2 ) as

test
left join app_test1 on test.tracknum = app_test1.tracknum
left join app_test2 on test.tracknum = app_test2.tracknum

我正在学习mysql。显示我知道有很多其他方法可以得到这个结果。首先我想知道的是上面的代码是正确的。有没有其他方法可以将该查询写得更短,如果是,请分享。

2 个答案:

答案 0 :(得分:1)

在MYSQL全外连接不工作我使用的替代方式是

SELECT * FROM ot_app_test1 left outer join app_test2 on app_test1.tracknum = app_test2.tracknum
union
SELECT * FROM ot_app_test1 right outer join app_test2 on app_test1.tracknum = app_test2.tracknum

试试吧

答案 1 :(得分:1)

具有两个联接的union是实现full outer join的一种方法。但是,它会带来很多开销,因为union消除了大量重复记录。

另一种方法是首先获取密钥列表,然后使用left join。重复消除在较小的集合上完成:

select billdt, tracknum, t1.ups_netchg, t2.optic_netchg
from (select billdt, tracknum from app_test1 union
      select billdt, tracknum from app_test2
     ) bt left join
     app_test1 t1
     using (billdt, tracknum) left join
     app_test2 t2
     using (billdt, tracknum);

或者,在您的情况下,因为没有重复项生成多行:

select billdt, tracknum, max(ups_netchg), max(ups_netchg2)
from (select billdt, tracknum, ups_netchg, NULL as ups_netchg2
      from app_test1
      union all
      select billdt, tracknum, ups_netchg, NULL as ups_netchg2
      from app_test2
     ) tt
group by billdt, tracknum;

如果性能完全成问题,我会尝试所有三种方法,看看哪种方法最适合你的情况。