Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL中的交叉连接与内部连接_Sql_Sql Server_Sql Server 2008_Tsql_Cross Join - Fatal编程技术网

SQL中的交叉连接与内部连接

SQL中的交叉连接与内部连接,sql,sql-server,sql-server-2008,tsql,cross-join,Sql,Sql Server,Sql Server 2008,Tsql,Cross Join,交叉连接和内部连接之间有什么区别 交叉连接: SELECT Movies.CustomerID, Movies.Movie, Customers.Age, Customers.Gender, Customers.[Education Level], Customers.[Internet Connection], Customers.[Marital Status], FROM Customers CROSS JOIN Movies S

交叉连接
内部连接
之间有什么区别

交叉连接:

SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status], 
FROM   
    Customers 
CROSS JOIN 
    Movies
SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status]
FROM   
    Customers 
INNER JOIN 
    Movies ON Customers.CustomerID = Movies.CustomerID
内部联接:

SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status], 
FROM   
    Customers 
CROSS JOIN 
    Movies
SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status]
FROM   
    Customers 
INNER JOIN 
    Movies ON Customers.CustomerID = Movies.CustomerID

哪一个更好?我为什么要使用其中一个

交叉连接不会合并行,如果每个表中有100行1对1匹配,则会得到10.000个结果,Innerjoin在相同情况下只会返回100行

这两个示例将返回相同的结果:

交叉连接

select * from table1 cross join table2 where table1.id = table2.fk_id
内连接

select * from table1 join table2 on table1.id = table2.fk_id

使用最后一种方法

在使用内部联接编写查询时,如果两个表上的条件都满足,记录将从两个表中提取,即两个表中的公共列完全匹配

使用交叉联接编写查询时,结果就像两个表中记录数的笛卡尔乘积。示例:如果表1包含2条记录,而表2包含3条记录,则查询结果为2*3=6条记录

所以,在需要交叉连接之前,不要使用交叉连接。

内部连接 仅显示两个联接表中匹配的行的联接称为内部联接。这是查询和视图设计器中的默认联接

内部联接的语法

SELECT t1.column_name,t2.column_name
FROM table_name1 t1
INNER JOIN table_name2 t2
ON t1.column_name=t2.column_name
交叉连接 一种交叉联接,生成联接中涉及的表的笛卡尔积。笛卡尔积的大小是第一个表中的行数乘以第二个表中的行数

交叉联接的语法

SELECT * FROM table_name1
CROSS JOIN table_name2
或者我们也可以用另一种方式来写

SELECT * FROM table_name1,table_name2
现在检查下面的交叉联接查询

select * from table1 cross join table2 where table1.id = table2.fk_id
范例

SELECT * FROM UserDetails
CROSS JOIN OrderDetails


下面是交叉连接和内部连接的最佳示例

考虑下表

表格:
教师

x------------------------x
| TchrId   | TeacherName | 
x----------|-------------x
|    T1    |    Mary     |
|    T2    |    Jim      |
x------------------------x
x--------------------------------------x
|  StudId  |    TchrId   | StudentName | 
x----------|-------------|-------------x            
|    S1    |     T1      |    Vineeth  |
|    S2    |     T1      |    Unni     |
x--------------------------------------x
表格:
学生

x------------------------x
| TchrId   | TeacherName | 
x----------|-------------x
|    T1    |    Mary     |
|    T2    |    Jim      |
x------------------------x
x--------------------------------------x
|  StudId  |    TchrId   | StudentName | 
x----------|-------------|-------------x            
|    S1    |     T1      |    Vineeth  |
|    S2    |     T1      |    Unni     |
x--------------------------------------x
1.内连接 内部联接选择同时满足两个表的行

我们需要找到的是班主任和相应的学生。在这种情况下,我们需要应用
连接
内部连接
,并将

查询

SELECT T.TchrId,T.TeacherName,S.StudentName 
FROM #Teacher T
INNER JOIN #Student S ON T.TchrId = S.TchrId
SELECT T.TchrId,T.TeacherName,S.StudentName 
FROM #Teacher T
CROSS JOIN #Student S 
结果

x--------------------------------------x
|  TchrId  | TeacherName | StudentName | 
x----------|-------------|-------------x            
|    T1    |     Mary    |    Vineeth  |
|    T1    |     Mary    |    Unni     |
x--------------------------------------x
x--------------------------------------x
|  TchrId  | TeacherName | StudentName | 
x----------|-------------|-------------x            
|    T2    |     Jim     |    Vineeth  |
|    T2    |     Jim     |    Unni     |
|    T1    |     Mary    |    Vineeth  |
|    T1    |     Mary    |    Unni     |
x--------------------------------------x
2。交叉连接 交叉联接选择第一个表中的所有行和第二个表中的所有行,并显示为笛卡尔积ie,具有所有可能性

考虑到我们需要在学校和学生中找到所有的老师,而不需要班主任,我们需要应用<代码>交叉连接< /代码>。

查询

SELECT T.TchrId,T.TeacherName,S.StudentName 
FROM #Teacher T
INNER JOIN #Student S ON T.TchrId = S.TchrId
SELECT T.TchrId,T.TeacherName,S.StudentName 
FROM #Teacher T
CROSS JOIN #Student S 
结果

x--------------------------------------x
|  TchrId  | TeacherName | StudentName | 
x----------|-------------|-------------x            
|    T1    |     Mary    |    Vineeth  |
|    T1    |     Mary    |    Unni     |
x--------------------------------------x
x--------------------------------------x
|  TchrId  | TeacherName | StudentName | 
x----------|-------------|-------------x            
|    T2    |     Jim     |    Vineeth  |
|    T2    |     Jim     |    Unni     |
|    T1    |     Mary    |    Vineeth  |
|    T1    |     Mary    |    Unni     |
x--------------------------------------x

请记住,如果添加WHERE子句,则交叉联接的行为与内部联接相同。例如,以下Transact-SQL查询生成相同的结果集。请参阅

SQL Server也接受以下更简单的表示法:

SELECT A.F, 
       B.G, 
       C.H 
  FROM TABLE_A A, 
       TABLE_B B, 
       TABLE_C C
 WHERE A.X = B.X 
   AND B.Y = C.Y
使用这种更简单的表示法,不必担心内部联接和交叉联接之间的差异。不是两个“ON”子句,而是一个“WHERE”子句。如果您在确定哪个“JOIN”“ON”子句的位置时遇到任何困难,请放弃“JOIN”符号,使用上面更简单的符号

这不是作弊。

交叉连接=(内部)连接=逗号(“,”)

TL;DRSQL交叉连接、(内部)连接和逗号(“,”)之间唯一的区别在于(内部)连接具有开启,而交叉连接和逗号不具有开启


Re中间产品


这三种方法都会产生一个中间概念性的SQL风格的关系“笛卡尔”产品,即交叉连接,它包含每个表中一行的所有可能组合。它是ON和/或WHERE,可减少行数

SQL标准定义了via产品(7.5 1.b.ii)、via交叉连接(7.7 1.a)和via plus上的(内部)连接(7.7 1.b)

正如维基百科所说:


交叉联接返回联接中表的行的笛卡尔积。换句话说,它将生成将第一个表中的每一行与第二个表中的每一行相结合的行


[…]联接的结果可以定义为首先获取表中所有记录的笛卡尔积(或交叉联接)(将表A中的每个记录与表B中的每个记录组合起来),然后返回满足联接谓词的所有记录的结果

“隐式连接表示法”只是在SELECT语句的FROM子句中列出要连接的表,并使用逗号将它们分隔开。因此,它指定了交叉连接

你看我的答案

重新外部联接并在vs上使用,在其中可以看到我的答案

为什么要在表之间比较列?

当没有重复行时:

每个表都包含从-[named-]blanks语句模板中的某个填充生成true语句的行。(它从满足某个(特征)谓词得出一个真命题。)

  • 基表包含从某个DBA给定语句模板生成true语句的行:

    /*行,其中
    客户C.CustomerID具有年龄C.年龄和。。。
    */
    来自客户C
    
  • 联接的中间乘积包含从其操作数模板的和生成true语句的行:

    /*行,其中
    客户C.CustomerID具有年龄C.年龄和。。。
    电影M.movie由客户M.CustomerID租用,并且。。。
    */
    来自客户C交叉连接电影M
    
  • ON&WHERE条件中添加AND以提供进一步的模板。该值也是满足该模板的行:

    /*行,其中
    客户C.CustomerID具有年龄C.年龄和。。。
    电影M.movie由客户M.CustomerID租用,并且。。。
    C.CustomerID=M.CustomerID
    C.年龄>=M[最低年龄]
    C.年龄=18岁
    */
    来自客户C
    
    | post_id | post_title | review    |
    |---------|------------|-----------|
    | 1       | Java       | Good      |
    | 1       | Java       | Excellent |
    | 2       | Hibernate  | Awesome   |