Pri*_*ton 133 sql t-sql sql-server cross-join sql-server-2008
CROSS JOIN和之间有什么区别INNER JOIN?
交叉加入:
SELECT
Movies.CustomerID, Movies.Movie, Customers.Age,
Customers.Gender, Customers.[Education Level],
Customers.[Internet Connection], Customers.[Marital Status],
FROM
Customers
CROSS JOIN
Movies
Run Code Online (Sandbox Code Playgroud)
内部联接:
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
Run Code Online (Sandbox Code Playgroud)
哪一个更好,为什么我会使用其中一个?
Sar*_*avu 176
这是交叉连接和内部连接的最佳示例.
请考虑以下表格
表: Teacher
x------------------------x
| TchrId | TeacherName |
x----------|-------------x
| T1 | Mary |
| T2 | Jim |
x------------------------x
Run Code Online (Sandbox Code Playgroud)
表: Student
x--------------------------------------x
| StudId | TchrId | StudentName |
x----------|-------------|-------------x
| S1 | T1 | Vineeth |
| S2 | T1 | Unni |
x--------------------------------------x
Run Code Online (Sandbox Code Playgroud)
内部联接选择满足两个表的行.
考虑一下我们需要找到班级老师及其相应学生的老师.在这种情况下,我们需要申请JOIN或INNER JOIN将会

询问
SELECT T.TchrId,T.TeacherName,S.StudentName
FROM #Teacher T
INNER JOIN #Student S ON T.TchrId = S.TchrId
Run Code Online (Sandbox Code Playgroud)
结果
x--------------------------------------x
| TchrId | TeacherName | StudentName |
x----------|-------------|-------------x
| T1 | Mary | Vineeth |
| T1 | Mary | Unni |
x--------------------------------------x
Run Code Online (Sandbox Code Playgroud)
交叉连接选择第一个表中的所有行和第二个表中的所有行并显示为笛卡尔积,即具有所有可能性
考虑我们需要找到学校中的所有教师和学生而不管班级教师,我们需要申请CROSS JOIN.

询问
SELECT T.TchrId,T.TeacherName,S.StudentName
FROM #Teacher T
CROSS JOIN #Student S
Run Code Online (Sandbox Code Playgroud)
结果
x--------------------------------------x
| TchrId | TeacherName | StudentName |
x----------|-------------|-------------x
| T2 | Jim | Vineeth |
| T2 | Jim | Unni |
| T1 | Mary | Vineeth |
| T1 | Mary | Unni |
x--------------------------------------x
Run Code Online (Sandbox Code Playgroud)
t-c*_*.dk 110
交叉连接不会组合行,如果每个表中有100行与1对1匹配,则得到10.000结果,Innerjoin在相同情况下只返回100行.
这两个示例将返回相同的结果:
交叉加入
select * from table1 cross join table2 where table1.id = table2.fk_id
Run Code Online (Sandbox Code Playgroud)
内部联接
select * from table1 join table2 on table1.id = table2.fk_id
Run Code Online (Sandbox Code Playgroud)
使用最后一种方法
phi*_*pxy 65
CROSS JOIN =(INNER)JOIN =逗号(",")
TL; DR SQL CROSS JOIN,(INNER)JOIN和逗号(",")之间的唯一区别(除了逗号具有较低的评估顺序优先级)是(INNER)JOIN具有ON而CROSS JOIN和逗号不具有ON.
重新中间产品
这三个产生了每个表中一行的所有可能组合的中间概念SQL样式关系"笛卡尔""交叉"乘积.它是ON和/或WHERE,减少行数.SQL小提琴
SQL标准通过产品(7.5 1.b.ii)定义 <逗号>,<交叉连接>通过<逗号>(7.7 1.a)和JOIN ON <搜索条件>通过<逗号>加WHERE(7.7 1.b)定义).
正如维基百科所说:
CROSS JOIN从连接中的表返回行的笛卡尔积.换句话说,它将产生将第一个表中的每一行与第二个表中的每一行组合在一起的行.
[...]连接的结果可以定义为首先获取表中所有记录的笛卡尔积(或交叉连接)的结果(将表A中的每个记录与表B中的每个记录组合)然后返回满足连接谓词的所有记录.
"隐式连接表示法"只是在SELECT语句的FROM子句中列出要加入的表,使用逗号分隔它们.因此,它指定了交叉连接
Re OUTER JOINs&ON vs WHERE in the LE JOIN(OUTER JOIN)vs INNER JOIN中的条件.
为什么比较表之间的列?
每个表都包含从某个fill-in-[ - ]空白语句模板中生成真实语句的行.(它得出了一个真正的命题 - 满足 -某个(特征)谓词.)
基表包含从某个DBA给定的语句模板生成true语句的行:
/* rows where
customer C.CustomerID has age C.Age and ...
*/
FROM Customers C
Run Code Online (Sandbox Code Playgroud)join的中间产品包含从其操作数模板的AND中生成真实语句的行:
/* rows where
customer C.CustomerID has age C.Age and ...
AND movie M.Movie is rented by customer M.CustomerID and ...
*/
FROM Customers C CROSS JOIN Movies M
Run Code Online (Sandbox Code Playgroud)ON和WHERE条件是AND以进一步提供模板.该值再次是满足该模板的行:
/* rows where
customer C.CustomerID has age C.Age and ...
AND movie M.Movie is rented by customer M.CustomerID and ...
AND C.CustomerID = M.CustomerID
AND C.Age >= M.[Minimum Age]
AND C.Age = 18
*/
FROM Customers C INNER JOIN Movies M
ON C.CustomerID = M.CustomerID
AND C.Age >= M.[Minimum Age]
WHERE C.Age = 18
Run Code Online (Sandbox Code Playgroud)特别是,比较列之间的相等性意味着从产品中保留的行与模板的连接表部分具有相同的值.巧合的是,通常通过表之间的相等比较来删除大量行 - 必要且充分的是表征所需的行.
只需为您想要的行的模板编写SQL!
重新查询(以及表与条件)的含义请参阅:
如何从另一个SQL表中获取两个不同列的匹配数据:内部联接和/或联盟?
从人类可读的描述中构造SQL查询是否有任何经验法则?
重载"交叉连接"
不幸的是,术语"交叉连接"用于:
这些不同的含义变得混乱.(例如,在此处的其他答案和评论中.)
使用CROSS JOIN vs(INNER)JOIN vs comma
共同的惯例是:
通常,对于WHERE,也保留不在表对上的条件.但是它们可能必须放在(n INNER)JOIN ON中,以便为RIGHT,LEFT或FULL(OUTER)JOIN的参数获取适当的行.
重新"不要使用逗号"混合逗号与显式JOIN会误导,因为逗号的优先级较低.但鉴于中间产品在CROSS JOIN,(INNER)JOIN和逗号含义中的作用,上述惯例的论据根本不使用它是不稳定的.CROSS JOIN或逗号就像(INNER)JOIN一样,处于TRUE状态.中间产品ON和WHERE都在相应的谓词中引入AND.然而,INNER JOIN ON可以被认为是 - 比如,只有在找到满足ON条件的一对输入行时才生成输出行 - 它仍会返回满足条件的交叉连接行.ON 必须在SQL中补充逗号的唯一原因是写OUTER JOIN.当然,表达应该明确其含义; 但是什么是明确的取决于什么是意味着什么.
Re Venn图表具有两个相交圆的维恩图可以说明相同输入的INNER,LEFT,RIGHT和FULL JOIN的输出行之间的差异.当ON无条件为TRUE时,INNER JOIN结果与CROSS JOIN相同.它还可以说明INTERSECT,UNION和EXCEPT 的输入和输出行.当两个输入具有相同的列时,INTERSECT结果与标准SQL NATURAL JOIN相同,并且EXCEPT结果与涉及LEFT和RIGHT JOIN的某些习语相同.但它并没有说明(INNER)JOIN如何工作.这只是乍看起来似是而非.它可以识别ON,PK(主键),FK(外键)和/或SELECT的特殊情况的输入和/或输出部分.要做到这一点,您只需要确定圆圈所代表的集合的元素究竟是什么.(哪些混乱的演示文稿从未说清楚.)(请记住,通常对于连接,输出行与输入行具有不同的标题.)
小智 23
仅显示在两个连接表中具有匹配项的行的连接称为内连接.这是查询和视图设计器中的默认连接.
内连接的语法
SELECT t1.column_name,t2.column_name
FROM table_name1 t1
INNER JOIN table_name2 t2
ON t1.column_name=t2.column_name
Run Code Online (Sandbox Code Playgroud)
交叉连接,用于生成参与连接的表的笛卡尔积.笛卡尔积的大小是第一个表中的行数乘以第二个表中的行数.
交叉连接的语法
SELECT * FROM table_name1
CROSS JOIN table_name2
Run Code Online (Sandbox Code Playgroud)
或者我们也可以用另一种方式写它
SELECT * FROM table_name1,table_name2
Run Code Online (Sandbox Code Playgroud)
现在检查以下查询以进行交叉连接
例
SELECT * FROM UserDetails
CROSS JOIN OrderDetails
Run Code Online (Sandbox Code Playgroud)
要么
SELECT * FROM UserDetails, OrderDetails
Run Code Online (Sandbox Code Playgroud)
Vla*_*cea 13
ACROSS JOIN 旨在生成笛卡尔积。
笛卡尔积采用两组 A 和 B,并从两组给定的数据中生成对记录的所有可能排列。
例如,假设您有以下ranks和suits数据库表:
并且ranks有以下几行:
| name | symbol | rank_value |
|-------|--------|------------|
| Ace | A | 14 |
| King | K | 13 |
| Queen | Q | 12 |
| Jack | J | 11 |
| Ten | 10 | 10 |
| Nine | 9 | 9 |
Run Code Online (Sandbox Code Playgroud)
虽然该suits表包含以下记录:
| name | symbol |
|---------|--------|
| Club | ? |
| Diamond | ? |
| Heart | ? |
| Spade | ? |
Run Code Online (Sandbox Code Playgroud)
作为 CROSS JOIN 查询,如下所示:
SELECT
r.symbol AS card_rank,
s.symbol AS card_suit
FROM
ranks r
CROSS JOIN
suits s
Run Code Online (Sandbox Code Playgroud)
将生成ranks和suites对的所有可能排列:
| card_rank | card_suit |
|-----------|-----------|
| A | ? |
| A | ? |
| A | ? |
| A | ? |
| K | ? |
| K | ? |
| K | ? |
| K | ? |
| Q | ? |
| Q | ? |
| Q | ? |
| Q | ? |
| J | ? |
| J | ? |
| J | ? |
| J | ? |
| 10 | ? |
| 10 | ? |
| 10 | ? |
| 10 | ? |
| 9 | ? |
| 9 | ? |
| 9 | ? |
| 9 | ? |
Run Code Online (Sandbox Code Playgroud)
另一方面,INNER JOIN 不返回两个连接数据集的笛卡尔积。
相反,INNER JOIN 从左侧表中获取所有元素,并将它们与右侧表中的记录进行匹配,以便:
例如,假设我们在父表post和子post_comment表之间有一个一对多的表关系,如下所示:
现在,如果该post表有以下记录:
| id | title |
|----|-----------|
| 1 | Java |
| 2 | Hibernate |
| 3 | JPA |
Run Code Online (Sandbox Code Playgroud)
并且该post_comments表有这些行:
| id | review | post_id |
|----|-----------|---------|
| 1 | Good | 1 |
| 2 | Excellent | 1 |
| 3 | Awesome | 2 |
Run Code Online (Sandbox Code Playgroud)
如下所示的 INNER JOIN 查询:
SELECT
p.id AS post_id,
p.title AS post_title,
pc.review AS review
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
Run Code Online (Sandbox Code Playgroud)
将包括所有post记录及其所有相关联post_comments:
| post_id | post_title | review |
|---------|------------|-----------|
| 1 | Java | Good |
| 1 | Java | Excellent |
| 2 | Hibernate | Awesome |
Run Code Online (Sandbox Code Playgroud)
基本上,您可以将其
INNER JOIN视为过滤后的 CROSS JOIN,其中只有匹配的记录保留在最终结果集中。
小智 11
请记住,如果添加WHERE子句,则交叉连接表现为内部联接.例如,以下Transact-SQL查询生成相同的结果集.请参阅http://technet.microsoft.com/en-us/library/ms190690(v=sql.105).aspx
小智 7
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
Run Code Online (Sandbox Code Playgroud)
使用这种更简单的表示法,不需要担心内部和交叉连接之间的差异.而不是两个"ON"子句,有一个"WHERE"子句来完成这项工作.如果您在确定哪个"JOIN""ON"子句去哪里时遇到任何困难,请放弃"JOIN"符号并使用上面更简单的符号.
这不是作弊.
| 归档时间: |
|
| 查看次数: |
351375 次 |
| 最近记录: |