|----------------------------|
| Tbl_1 |
|--------------|-------------|
| id | name_1 |
|--------------|-------------|
| 1 | t_1_rec_1 |
|--------------|-------------|
|------------------------------------------------------------|
| Tbl_2 |
|-------|--------------|-----------|------------|------------|
| id | name_2 | tbl_1_id | tbl_3_id | tbl_4_id |
|-------|--------------|-----------|------------|------------|
| 1 | t_2_rec_1 | 1 | 1 | 2 |
| 2 | t_2_rec_2 | 1 | 2 | 1 |
|-------|--------------|-----------|------------|------------|
|------------------------|
| Tbl_3 |
|----------|-------------|
| id | name_3 |
|----------|-------------|
| 1 | t_3_rec_1 |
| 2 | t_3_rec_2 |
|----------|-------------|
|----------------------|
| Tbl_4 |
|--------|-------------|
| id | name_4 |
|--------|-------------|
| 1 | t_4_rec_1 |
| 2 | t_4_rec_2 |
|--------|-------------|
|--------------------------------------------|
| Tbl_5 |
|------|------------|------------|-----------|
| id | name_5 | tbl_2_id | tbl_6_id |
|------|------------|------------|-----------|
| 1 | t_5_rec_1 | 1 | 1 |
| 2 | t_5_rec_2 | 1 | 2 |
|------|------------|------------|-----------|
|----------------------------------|
| Tbl_6 |
|-------|------------|
| id | name_6 |
|-------|------------|
| 1 | t_6_rec_1 |
| 2 | t_6_rec_2 |
|-------|------------|
我期待这些结果:
t1.name_1 t2.name_2 t3.name_3 t4.name_4 t5.name_5 t6.name_6
t_1_rec_1 t_2_rec_1 t_3_rec_1 t_4_rec_2 t_5_rec_1 t_6_rec_1
t_1_rec_1 t_2_rec_1 t_3_rec_1 t_4_rec_2 t_5_rec_2 t_6_rec_2
t_1_rec_1 t_2_rec_2 t_3_rec_2 t_4_rec_1
select t1.name_1, t2.name_2, t3.name_3, t4.name_4, t5.name_5, t6.name_6
from Tbl_1 as t1
left join Tbl_2 as t2 on t2.id = t1.id
inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id
inner join Tbl_4 as t4 on t2.tbl_4_id = t4.id
left join Tbl_5 as t5 on t5.id = t2.id
inner join Tbl_6 as t6 on t2.tbl_6_id = t6.id
但这不起作用!!!!!第三行未返回。将最后一个内连接(Tbl_6)更改为左连接会产生第三行。
我理解Tbl_5和Tbl_6之间的内部连接将导致没有Tbl_5记录但是我希望Tbl_2和Tbl_5之间的左连接将导致Tbl_2并且其内部连接的Tbl_3和Tbl_4记录在那里并且因此Tbl_1离开加入Tbl_2,我会得到第三行。
我错过了什么? (我宁愿不必更改内连接,因为我不希望Tbl_5记录在后面没有Tbl_6条目)此外,此查询是从Zend Db类生成的,我需要能够将任何答案纳入其中,但我想如果有一个正常的查询,或者正如我所期望的那样,那么我将弄清楚如何让Zend生成它......
答案 0 :(得分:0)
在SQL(和MySQL)中,inner join
,left outer join
,right outer join
和cross join
操作都具有相同的优先级。因此,a left join b inner join c
是(a left join b) inner join c
。同样,算术表达式1 - 2 + 3
为(1 - 2) + 3
而不是1 - (2 + 3)
。
考虑到这一点,让我们看一下你的from
条款:
from Tbl_1 as t1
left join Tbl_2 as t2 on t2.id = t1.id
inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id
inner join Tbl_4 as t4 on t2.tbl_4_id = t4.id
left join Tbl_5 as t5 on t5.id = t2.id
inner join Tbl_6 as t6 on t2.tbl_6_id = t6.id
第一个内部联接是t2.tbl_3_id = t3.id
。如果t2.tbl_3_id
表上的t1
没有匹配,则列t2
将为NULL。由于NULL
值不匹配,因此效果是将第一个连接转换为内连接。
您可以使用以下语法解决此问题:
inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id or t2.id is null
(NULL比较是t2.id
而不是t2.tbl_3_id
,以防id在有效匹配中id为NULL。)
您可以为后续连接继续此逻辑。
外连接和内连接的混合不会自动将外连接转换为内连接。这取决于on
子句中的条件。
就个人而言,我发现遵循连接的语义相当繁琐。我只使用内连接或只使用左外连接来编写几乎所有查询。也就是说,要么保留所有匹配的行,要么保留第一个表中的所有行。
如果我想混合连接类型,那么我有两个选择。第一种是使用子查询 - 在MySQL中,可能会导致性能问题。或者,我使用left outer join
并在where
子句中添加条件以实现我想要的逻辑。