加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL使用外部引用嵌套左连接

发布时间:2020-12-11 23:38:16 所属栏目:MySql教程 来源:网络整理
导读:假设我们有这些(从更复杂的一个简化)示例表: == st == == pr === == rn === 我想用左内连接执行这个(也简化的)查询: SELECT st.*,pr.*,rn.*FROM stINNER JOIN ( prLEFT JOIN rn ON pr.rou = rn.rou AND rn.sta = st.sta -- ERROR here ) ON pr.pg = st.pg-

假设我们有这些(从更复杂的一个简化)示例表:

== st ==    == pr ===   == rn ===  <– tables
sta   pg    pg    rou   sta   rou  <– fields
========    =========   =========
H1    aa    aa    aaA   H1    aaA

H2    aa    aa    aaB   H2    aaB
H3    aa                H3    aaB

H4    aa    aa    aaC   H4    aaC
H5    aa                H5    aaC
H6    aa                H6    aaC

H7    aa

H8    bb    bb    NULL

我想用左内连接执行这个(也简化的)查询:

SELECT st.*,pr.*,rn.*
FROM         st
INNER JOIN ( pr
LEFT  JOIN   rn  ON pr.rou = rn.rou
                AND          rn.sta = st.sta -- ERROR here
           )     ON pr.pg =           st.pg
-- filter out bad rows
WHERE ( rn.id )                          -- a: not null
   OR ( pr.rou ='aaC' AND rn.id IS NULL) -- b: no joinable rn found: choose
                                         --    by a predefined pr.rou value
   OR ( pr.rou IS NULL )                 -- c: no need to join

得到这个结果:

== st ==    == pr ===   == rn ===
sta   pg    pg    rou   sta   rou
========    =========   =========
H1    aa    aa    aaA   H1    aaA
H2    aa    aa    aaB   H2    aaB
H3    aa    aa    aaB   H3    aaB
H4    aa    aa    aaC   H4    aaC
H5    aa    aa    aaC   H5    aaC
H6    aa    aa    aaC   H6    aaC

H7    aa    aa    aaA   NULL  NULL   H7 has no rn,so choose
H7    aa    aa    aaB   NULL  NULL  } 1 row of these at the
H7    aa    aa    aaC   NULL  NULL /  WHERE / b condition

H8    bb    bb    NULL  NULL  NULL

但MySQL抛出了这个错误:#1054 – ‘on子句’中的未知列’st.sta’.

我试图解决这个问题没有成功,直到有人发布(并删除)了两次加入rn列的好主意.感谢他/她,我能够创建一个有效的解决方案:

SELECT st.*,rn.*,rn2.*

FROM         st
INNER JOIN   pr         ON st.pg = pr.pg
LEFT  JOIN   rn         ON st.sta = rn.sta
LEFT  JOIN   rn AS rn2  ON pr.rou = rn2.rou -- the two rn's join order is important
                       AND rn.id  = rn2.id  -- if first exists,second must match or null,first null => second null
WHERE ( rn.id = rn2.id )                    -- a: both not null
   OR ( pr.rou ='aaC' AND rn.id IS NULL)    -- b: no joinable rn found: choose by predefined pr.rou value
   OR ( pr.rou IS NULL )                    -- c: no need to join

虽然这个查询有效,但它需要以正确的顺序重复连接,非常脆弱和丑陋.

你能提供一个更清洁的解决方案,它只连接一次rn表吗?

这是sql中用于copypasting的示例数据库,如果你想玩它:

DROP    TABLE IF     EXISTS st;
CREATE  TABLE IF NOT EXISTS st (
  id  int  AUTO_INCREMENT,sta varchar(9),pg  varchar(9),PRIMARY KEY ( id )
)  AUTO_INCREMENT=1;

DROP    TABLE IF     EXISTS pr;
CREATE  TABLE IF NOT EXISTS pr (
  id  int  AUTO_INCREMENT,rou varchar(9),PRIMARY KEY ( id )
)  AUTO_INCREMENT=1;

DROP    TABLE IF     EXISTS rn;
CREATE  TABLE IF NOT EXISTS rn (
  id  int  AUTO_INCREMENT,PRIMARY KEY ( id )
)  AUTO_INCREMENT=1;


INSERT INTO st 
(sta,pg ) VALUES
('H1','aa'),('H2',('H3',('H4',('H5',('H6',('H7',('H8','bb');
INSERT INTO pr
( pg,rou ) VALUES
('aa','aaA'),('aa','aaB'),'aaC'),('bb',NULL);
INSERT INTO rn
(sta,rou ) VALUES
('H1','aaC');
最佳答案 我想我终于明白了:

SELECT st.*,rn.*
FROM st
  LEFT JOIN rn ON st.sta = rn.sta
  LEFT JOIN pr ON st.pg  = pr.pg
              AND (rn.rou = pr.rou OR rn.rou IS NULL)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读