1
|----------------------------|
|  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 left join to Tbl_2 我会得到第三行。

我错过了什么?(我宁愿不必更改内部连接,因为我不希望 Tbl_5 记录在后面没有 Tbl_6 条目)此外,此查询是从 Zend Db 类生成的,我需要能够将任何答案纳入其中,但我想如果有一个正常工作的查询,或者正如我所期望的那样,那么我将弄清楚如何让 Zend 产生它......

4

1 回答 1

0

在 SQL(和 MySQL)中inner joinleft outer joinright outer join、 和cross join操作都具有相同的优先级。所以,a left join b inner join c(a left join b) inner join c。同理,算术表达式1 - 2 + 3is(1 - 2) + 3和 not 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该列将为 NULL t2。因为NULL值不匹配,所以效果是将第一个连接变成内部连接。

您可以使用以下语法解决此问题:

inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id or t2.id is null

(NULL 比较是为了,t2.idt2.tbl_3_id不仅仅是在有效匹配中 id 可能为 NULL 的情况下。)

您可以为后续连接继续此逻辑。

外部联接和内部联接的混合不会自动将外部联接转换为内部联接。这取决于on子句中的条件。

就个人而言,我发现遵循连接的语义相当麻烦。我几乎所有的查询都只使用内连接或左外连接。也就是说,要么保留所有匹配的行,要么保留第一个表中的所有行。

如果我想混合连接类型,那么我有两个选择。第一种是使用子查询——在 MySQL 中,这会导致性能问题。或者,我使用left outer joins 并在where子句中添加条件来实现我想要的逻辑。

于 2013-05-11T22:45:13.800 回答