交叉连接的意外结果

时间:2016-04-13 11:35:40

标签: sql sql-server cross-join

这些是我的 tblEmp 表和 tblDept 表(我正在使用MS-SQL Server 2012),当我尝试在这两个表上使用交叉连接时,它给出了我没想到的结果,只是想知道为什么这个交叉连接给出了这样的结果,谢谢。

ID  Name  Gender    Salary  Dept_id
1   abc   male      2004    1
2   Tom   female    5004    2
3   Sara  female    29404   2
4   Jim    male     8604    3
5   Lisan   male    2078    1
6   Brad    male    9804    3
7   Diana   female  2095    2
8   Henry   male    28204   2
9   Mark    male    20821   1
10  Miley   female  9456    1
11  Richie  male    8604    NULL
12  Lisan   female  20776   NULL
  

tblDept

ID  Dept_Name         Location
1   IT                Mumbai
2   HR                Delhi
3   Accounts          London
4   OtherDepartment   NewYork

这是交叉连接查询及其输出

select Name, Gender, Salary, Dept_Name
from tblEmp 
CROSS JOIN tblDept 
where tblEmp.Dept_id is NULL

输出

Name    Gender  Salary  Dept_Name
Richie  male    8604    IT
Richie  male    8604    HR
Richie  male    8604    Accounts
Richie  male    8604    OtherDepartment
Lisan   female  20776   IT
Lisan   female  20776   HR
Lisan   female  20776   Accounts
Lisan   female  20776   OtherDepartment

我的期望是这样的

    Name    Gender  Salary  Dept_Name
    Richie  male    8604    NULL
    Richie  male    8604    NULL
    Richie  male    8604    NULL
    Richie  male    8604    NULL
    Lisan   female  20776   NULL
    Lisan   female  20776   NULL
    Lisan   female  20776   NULL
    Lisan   female  20776   NULL

3 个答案:

答案 0 :(得分:1)

结果是正确的,ReadPort called completion_condition: bytes transferred: 0 of 1024 => continue! completion_condition: bytes transferred: 8 of 1024 => continue! ... completion_condition: bytes transferred: 88 of 1024 => continue! completion_condition: bytes transferred: 96 of 1024 => continue! timeoutHandler called cancel of seriel port. completion_condition received error code: The I/O operation has been aborted because of either a thread exit or an application request completion handler called with error code: The I/O operation has been aborted because of either a thread exit or an application request 会根据两个表格为您提供所有组合:cross jointblEmp

由于您使用tblDept作为组合,没有where子句,它将为您提供两个表之间的所有组合:

Dept_Name

也就是说,通过交叉加入,您实际上会获得12(来自Name Gender Salary Dept_Name abc male 2004 IT abc male 2004 HR abc male 2004 Accounts abc male 2004 OtherDepartment Tom female 5004 IT Tom female 5004 HR Tom female 5004 Accounts Tom female 5004 OtherDepartment ... and so on Richie male 8604 IT Richie male 8604 HR Richie male 8604 Accounts Richie male 8604 OtherDepartment Lisan female 20776 IT Lisan female 20776 HR Lisan female 20776 Accounts Lisan female 20776 OtherDepartment )x 4(来自tblEmp)= 48行

然后你的where子句会删除除tblDeptRichie之外的所有人,因为他们中的两个是唯一拥有Lisan

的人
Dept_id = NULL

如果您也查询Name Gender Salary Dept_Name Richie male 8604 IT Richie male 8604 HR Richie male 8604 Accounts Richie male 8604 OtherDepartment Lisan female 20776 IT Lisan female 20776 HR Lisan female 20776 Accounts Lisan female 20776 OtherDepartment 列,

Dept_id

结果将更加清晰,因为您实际上只有select Name, Gender, Salary, Dept_id, Dept_Name from tblEmp CROSS JOIN tblDept where tblEmp.Dept_id is NULL 的员工:

Dept_id = NULL

您的Name Gender Salary Dept_id Dept_Name Richie male 8604 NULL IT Richie male 8604 NULL HR Richie male 8604 NULL Accounts Richie male 8604 NULL OtherDepartment Lisan female 20776 NULL IT Lisan female 20776 NULL HR Lisan female 20776 NULL Accounts Lisan female 20776 NULL OtherDepartment 列来自4个Dept_Name条目,而不是来自tblDept条目。

答案 1 :(得分:0)

如果您需要显示所有员工及其部门,您可以使用LEFT JOIN:

SELECT Name, Gender, Salary, Dept_Name
FROM 
    tblEmp AS E
    LEFT JOIN
    tblDept AS D
        ON E.Dept_id = D.ID

结果:

Name    Gender  Salary  Dept_Name 
abc     male    2004    IT 
Tom     female  5004    HR 
Sara    female  29404   HR 
Jim     male    8604    Accounts 
Lisan   male    2078    IT 
Brad    male    9804    Accounts 
Diana   female  2095    HR 
Henry   male    28204   HR 
Mark    male    20821   IT 
Miley   female  9456    IT 
Richie  male    8604    NULL 
Lisan   female  20776   NULL

OR

如果您需要显示所有员工和所有部门,您可以使用FULL JOIN:

SELECT Name, Gender, Salary, Dept_Name
FROM 
    tblEmp AS E
    FULL JOIN
    tblDept AS D
        ON E.Dept_id = D.ID

结果:

Name    Gender  Salary  Dept_Name
abc     male    2004    IT
Tom     female  5004    HR
Sara    female  29404   HR
Jim     male    8604    Accounts
Lisan   male    2078    IT
Brad    male    9804    Accounts
Diana   female  2095    HR
Henry   male    28204   HR
Mark    male    20821   IT
Miley   female  9456    IT
Richie  male    8604    NULL
Lisan   female  20776   NULL
NULL    NULL    NULL    OtherDepartment

答案 2 :(得分:0)

如果您确实希望每个具有null dept_id的每个部门都有一个NULL行,例如

select Name, Gender, Salary, NULL AS Dept_Name
from tblEmp 
CROSS JOIN tblDept 
where tblEmp.Dept_id is NULL

你可以执行这个......

T