Mixing inner join and outer join

本文通过具体的SQL查询语句展示了左外连接和内连接的不同效果,并解释了为何部分记录在进行内连接后会丢失。通过使用子查询的方法解决了这一问题,确保所有部门信息都能被正确展示。
SQL< show rel
release 1102000300

SQL< select dept.deptno, emp.ename
from dept left outer join emp on dept.deptno=emp.deptno
order by deptno nulls last;

    DEPTNO ENAME
---------- ----------
        10 az
        10 MILLER
        10 KING
        10 CLARK
        20 JONES
        20 SMITH
        20 FORD
        20 ADAMS
        20 SCOTT
        30 ALLEN
        30 TURNER
        30 JAMES
        30 WARD
        30 BLAKE
        30 MARTIN
        40

16 rows selected.

Let's see what happens after inner joining to bonus table.
SQL< select dept.deptno, emp.ename, bonus.comm
from dept left outer join emp on dept.deptno=emp.deptno
inner join bonus on emp.ename = bonus.ename
order by deptno nulls last;  

    DEPTNO ENAME            COMM
---------- ---------- ----------
        10 az                 .1
        10 MILLER             .1
        10 KING               .1
        10 CLARK              .1
        20 JONES              .1
        20 SMITH              .1
        20 FORD               .1
        20 ADAMS              .1
        20 SCOTT              .1
        30 ALLEN              .1
        30 TURNER             .1
        30 JAMES              .1
        30 WARD               .1
        30 BLAKE              .1
        30 MARTIN             .1

15 rows selected.
One row where deptno=40 is missing. The reason is that : 
Oracle first processes the left outer join, the intermediate result has a row: deptno=40 ename is null. When Oracle does inner join, this row  does not satisfy the inner join condition, therefore, it's ruled out from the final result.

In oracle null does not equal null, so even if there's a row with null ename, this row does not show up in the final result.

Here, we need a sub-query:

select dept.deptno, em.ename, em.comm 
from dept left outer join (
select emp.deptno, emp.ename, bonus.comm
from emp inner join bonus on emp.ename = bonus.ename 
order by emp.deptno nulls last) em
on dept.deptno=em.deptno;

    DEPTNO ENAME            COMM
---------- ---------- ----------
        10 az                 .1
        10 MILLER             .1
        10 KING               .1
        10 CLARK              .1
        20 JONES              .1
        20 SMITH              .1
        20 FORD               .1
        20 ADAMS              .1
        20 SCOTT              .1
        30 ALLEN              .1
        30 TURNER             .1
        30 JAMES              .1
        30 WARD               .1
        30 BLAKE              .1
        30 MARTIN             .1
        40

16 rows selected.







### ### 混合使用位置参数和关键字参数的最佳实践 在 Python 中,函数调用可以混合使用位置参数和关键字参数,但必须遵循严格的顺序规则:**位置参数必须出现在关键字参数之前**。这种设计确保了参数绑定的清晰性和一致性,避免了歧义。例如,以下调用是合法的: ```python def describe_pet(animal_type, pet_name): print(f"I have a {animal_type} named {pet_name}.") describe_pet('hamster', pet_name='Harry') # 正确 ``` 如果尝试将关键字参数放在位置参数之前,则会引发 `SyntaxError`: ```python describe_pet(pet_name='Harry', 'hamster') # 错误:位置参数在关键字参数后 ``` 此外,不能对同一个参数进行多次赋值,无论是通过位置还是关键字形式: ```python describe_pet('hamster', animal_type='dog', pet_name='Harry') # 错误:多次赋值 ``` 这种限制有助于防止因参数重复赋值而导致的逻辑错误。 ### ### 保持清晰的参数顺序与命名 为了提高代码的可读性和可维护性,建议在函数调用中优先使用关键字参数,尤其是在参数数量较多或某些参数具有默认值的情况下。例如: ```python def send_email(to, subject="No Subject", body=""): print(f"Sending email to {to} with subject '{subject}' and body '{body}'") send_email(to="alice@example.com", body="Meeting rescheduled.") ``` 通过显式指定参数名称,调用者可以清晰地表达每个参数的用途,而无需依赖参数顺序。这种做法在团队协作和长期维护中尤为重要。 ### ### 利用默认参数增强灵活性 关键字参数通常与默认参数值结合使用,以增强函数的灵活性。例如: ```python def calculate_discount(price, discount_rate=0.1, tax_rate=0.05): discounted_price = price * (1 - discount_rate) final_price = discounted_price * (1 + tax_rate) return final_price print(calculate_discount(100, discount_rate=0.2)) # 输出: 84.0 ``` 在上述代码中,`price` 是位置参数,而 `discount_rate` 是关键字参数,`tax_rate` 使用了默认值。这种方式允许调用者仅指定需要修改的参数,而其余参数使用默认值。 ### ### 避免关键字参数与位置参数的混淆 在定义函数时,需要注意默认参数的设置方式。例如,以下函数定义中,`x`、`y` 和 `z` 是具有默认值的参数,而不是关键字参数: ```python def text(x=8, y=9, z=10, *args): print(x) print(y) print(z) print(args) ``` 在调用时,这些参数可以通过位置或关键字形式传入,但它们的默认值仅在未提供参数时生效。 ### ### 总结 混合使用位置参数和关键字参数的最佳实践包括: - 位置参数必须在关键字参数之前。 - 避免对同一个参数多次赋值。 - 优先使用关键字参数以提高可读性,尤其是在参数数量较多或有默认值的情况下。 - 合理使用默认参数值,以增强函数的灵活性和可维护性。 通过遵循这些规则,可以编写出更清晰、安全且易于维护的函数调用代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值