;WITH tblEmployee AS (
SELECT * FROM (VALUES
(1, 'Tom', 'Male', 4000, 1),
(2, 'Pam', 'Female', 3000, 3),
(3, 'John', 'Male', 3500, 1),
(4, 'Sam', 'Male', 4500, 2),
(5, 'Todd', 'Male', 2800, 2),
(6, 'Ben', 'Male', 7000, 1),
(7, 'Sara', 'Female', 4800, 3),
(8, 'Valarie', 'Female', 5500, 1),
(9, 'James', 'Male', 6500, NULL),
(10, 'Russell', 'Male', 8800, NULL)) AS E(ID, Name, Gender, Salary, DepartmentId)
),
tblDepartment AS (
SELECT * FROM (VALUES
(1, 'IT', 'London', 'Rick'),
(2, 'Payroll', 'Delhi', 'Ron'),
(3, 'HR', 'New York', 'Christie'),
(4, 'Other Department', 'Sydney', 'Cindrella')) AS D(Id, DepartmentName, Location, DepartmentHead)
)
左表是员工表和右表部门表。
我正在网上阅读教程,并对教师提供的解释感到困惑:
如果我在上面的两个表上运行此查询:
Select E.Name, E.Gender, E.Salary, D.DepartmentName
from tblEmployee as E
Left Join tblDepartment as D
On tblEmployee.departmentID = tblDepartment.Id
Where tblEmployee.departmentID IS Null;
我对上面SQL代码中的最后一行有点困惑。当你说:
Where tblEmployee.departmentID IS Null
上面的代码行是否在运行这些代码行之后形成的新表上执行:
Select E.Name, E.Gender, E.Salary, D.DepartmentName
from tblEmployee as E
Left Join tblDepartment as D
On tblEmployee.departmentID = tblDepartment.Id
所以基本上它会检查所形成的新表:只有将部门ID作为NULL的地方才会显示这些行。我只是想澄清这一行:Where tblEmployee.departmentID IS Null
是在新表格形成正确后运行的?
答案 0 :(得分:1)
“ SQL Intelligent Joins”是一个罕见的措词。实际上,唯一的可靠参考(以及此问题中的数据集)来自YouTube SQL教程:
Advanced or Intelligent Joins by Kudvenkat
简而言之,“智能联接”的语法更简洁,而在声明数据集的边界时则更为明确。以以下两个查询为例。它们具有相同的输出,但是语法不同:
-- intelligent join
select
e.Name,
e.Gender,
e.Salary
from tblEmployee as e
left join tblDepartment as d on e.departmentID = d.Id
and d.DepartmentName = 'IT'
where
d.DepartmentName is null
上面的查询使用“智能联接”。
-- where clause subquery
select
e.Name,
e.Gender,
e.Salary
from tblEmployee as e
where
e.departmentID not in (select id from tblDepartment where departmentName = 'IT')
or e.departmentID is null
上面的此查询在where
子句中使用子查询。
但是,即使两个输出是等效的,第一个查询也更简单,并提供了更多信息。它的本质是“如果不在IT部门,请给我所有雇员的性别和薪水”。相反,where
子句子查询语法较长,并且混淆了表的联接方式。如果有的话,请尝试首先使用智能联接来实现所需的输出。
答案 1 :(得分:0)
这是一个左外连接。这会将public class MainActivity extends AppCompatActivity {
private String layoutName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.layoutName = getResources().getResourceEntryName(R.layout.activity_main);
Log.d("TAG", layoutName);
}
}
中未加入tblEmployee
的所有记录。
答案 2 :(得分:0)
OP的假设是正确的,以下是有关SQL
JOIN 语法的一些方面,对于初学者一旦掌握了 join的概念将有所帮助是。通常,仅仅知道某件事是正确的或有效的还不够,我们需要了解其背后的原因。
This answer from @fqhv使用了我个人最喜欢的有关不同连接类型的信息图形之一。
首先,请注意查询this reference is a good general explanation的执行顺序,请注意,每个数据库引擎可以并且可能会做不同的事情,但这是一个普遍的期望。
一个重要的要点是:
联接语句实际上是查询中
FROM
子句的一部分
请注意,在过滤后 发生后,如何评估select
语句,这意味着直到那时我们都可以考虑使用FROM
子句来表示一个非常宽的表其中包含FROM
子句中表示的表的 ALL 中的 ALL 列。
您可以通过在select语句中使用字段通配符(*
,星号)来演示此操作,而不用指定任何特定字段。
-在此示例中,我将注释掉SELECT
和WHERE
子句,以演示调试或研究SQL结果的常用技术。
-注意:由于在FROM
子句中使用了表别名,因此我已将查询更改为使用那些别名代替表名,该查询实际上将立即运行。
-我们希望所有列和所有行都将在以下查询中返回
-- Select E.Name, E.Gender, E.Salary, D.DepartmentName
SELECT *
from tblEmployee as E
Left Join tblDepartment as D
On E.departmentID = D.Id
-- Where E.departmentID IS Null;
ID Name Gender Salary DepartmentId Id DepartmentName Location DepartmentHead
----------- ------- ------ ----------- ------------ ----------- ---------------- -------- --------------
1 Tom Male 4000 1 1 IT London Rick
2 Pam Female 3000 3 3 HR New York Christie
3 John Male 3500 1 1 IT London Rick
4 Sam Male 4500 2 2 Payroll Delhi Ron
5 Todd Male 2800 2 2 Payroll Delhi Ron
6 Ben Male 7000 1 1 IT London Rick
7 Sara Female 4800 3 3 HR New York Christie
8 Valarie Female 5500 1 1 IT London Rick
9 James Male 6500 NULL NULL NULL NULL NULL
10 Russell Male 8800 NULL NULL NULL NULL NULL
(10 rows affected)
希望,从查询中查看结果确实应该在您可以选择和过滤的字段上描绘出一幅图画。
您会注意到,使用LEFT JOIN
导致某些行仅包含NULL
表中字段的tblDepartment
值。 LEFT OUTER JOIN
OUTER
或OUTER
,则INNER
是JOIN的默认修饰符。将其称为LEFT JOIN
对于当前JOIN
语句的 LEFT 中的每个结果,至少返回1行,也就是将先前联接到FROM
子句上的所有字段,即使我们刚刚加入的表中没有匹配的行。
有了这些信息,当我们想要列出不在任何部门中的所有学生的列表时,我们可以简单地使用插入空值的LEFT JOIN
行为轻松地确定要删除的行。
将Where E.departmentID IS Null
添加到查询中时,将仅返回没有部门的行。
-- Select E.Name, E.Gender, E.Salary, D.DepartmentName
SELECT *
from tblEmployee as E
Left Join tblDepartment as D
On E.departmentID = D.Id
Where E.departmentID IS Null;
ID Name Gender Salary DepartmentId Id DepartmentName Location DepartmentHead
----------- ------- ------ ----------- ------------ ----------- ---------------- -------- --------------
9 James Male 6500 NULL NULL NULL NULL NULL
10 Russell Male 8800 NULL NULL NULL NULL NULL
值得说明的是,这是一个非常简单的示例,完全不需要使用
JOIN
即可获得相似的结果,但这是演示所有类型JOIN的良好数据集。
例如,即使先前JOINed字段中没有匹配的行,RIGHT JOIN
也会为JOINed表中的每个结果返回至少一行。
SELECT *
from tblEmployee as E
RIGHT Join tblDepartment as D
On E.departmentID = D.Id
ID Name Gender Salary DepartmentId Id DepartmentName Location DepartmentHead
----------- ------- ------ ----------- ------------ ----------- ---------------- -------- --------------
1 Tom Male 4000 1 1 IT London Rick
3 John Male 3500 1 1 IT London Rick
6 Ben Male 7000 1 1 IT London Rick
8 Valarie Female 5500 1 1 IT London Rick
4 Sam Male 4500 2 2 Payroll Delhi Ron
5 Todd Male 2800 2 2 Payroll Delhi Ron
2 Pam Female 3000 3 3 HR New York Christie
7 Sara Female 4800 3 3 HR New York Christie
NULL NULL NULL NULL NULL 4 Other Department Sydney Cindrella
使用这些信息,我们现在可以轻松地过滤结果以显示所有拥有 0 名员工的部门:
SELECT *
from tblEmployee as E
RIGHT Join tblDepartment as D
On E.departmentID = D.Id
Where E.ID IS Null;
ID Name Gender Salary DepartmentId Id DepartmentName Location DepartmentHead
----------- ------- ------ ----------- ------------ ----------- ---------------- -------- --------------
NULL NULL NULL NULL NULL 4 Other Department Sydney Cindrella
这确实是一些点击诱饵,这不是一个名词,您会发现很多书都同意,但是我们都支持它的想法:
一个好的SQL程序员或DBA应该开发一种如何翻译查询要求的技能,并智能地应用
JOIN
语句来简化要求。
使用JOIN的 intelligent 应用程序可以解决开发人员本能遍历集合的许多问题,但不是全部,而是很多。因此,当您第一次想到 iterate 时,需要花一些时间来探索数据查询中的不同JOIN
语句。
您当然可以通过将专门针对JOINed表运行的过滤器条件移至以下位置,使实现JOIN
语句和复杂WHERE
子句的查询变得更智能,更易于阅读,从而使它们更易于阅读。 JOIN
表达式本身,它不在OP原始问题的范围内,无法通过此数据集解决,但@alexusWong goes into this in his response
WHERE
语句作为{{1}的附加条件} statemet。