上周我接受了技术面试,我的面试官问我如果运行以下查询会发生什么:
SELECT * FROM tbl1, tbl2
我想我的答案是正确的,但这不是一个深入的答案。
我说我会选择两个表中的所有列。例如,如果tbl1有3列,tbl2有4列。结果集将有7列。
然后他问我为什么7?我说因为我从每张桌子上选择了所有东西。
这是一个糟糕的答案,但我想不出别的什么。
为了减少追捕,在采访之后,我使用两张表执行了后一种说法。
表A中有3只动物:狗,猫和大象。
表B有2个名字:Mat和Beth
这是我在执行语句后得到的结果集:
*********************************************
| id_tbl1 | name_tbl1 | id_tbl2 | name_tbl2 |
*********************************************
| 1 | dog | 1 | Mat |
| 2 | cat | 1 | Mat |
| 3 | elephant | 1 | Mat |
| 1 | dog | 2 | Beth |
| 2 | cat | 2 | Beth |
| 3 | elephant | 2 | Beth |
*********************************************
所以我的问题是,为什么声明的表现如此?
换句话说:
为什么表B的记录重复,直到我到达表A的末尾,然后它重新开始?
你怎么能以某种方式回答这个问题呢?这对于面试官来说会是什么?
如果此问题不属于SO,请随时删除或关闭它!
答案 0 :(得分:7)
如果选择这样,则一个结果集中的所有行都将连接到另一个结果集中的所有行(笛卡尔积)。
因此,您将获得第一个表的所有行的列表以及第二个表的第一行,然后是第二行的所有条目,依此类推。订单可以是实施细节。不确定第一个订单是否由第一个表定义,它可能在实现之间有所不同。 如果连接三个表(或更多),则所有表的所有行都会发生相同的情况。当然,这不仅适用于表,也适用于任何来自连接的结果集。
答案 1 :(得分:4)
结果将是一个cartisian产品 看一下这个例子
你可以看到有两个表,一个有5个记录,另一个有4个,结果是20个记录。意味着你假设5 * 4 = 20而不是5 + 4 = 9。
表1
| IDX | VAL |
---------------
| 1 | 1val1 |
| 1 | 1val2 |
| 2 | 2val1 |
| 2 | 2val2 |
| 2 | 2val3 |
表2
| ID | POINTS |
---------------
| 1 | 2 |
| 2 | 10 |
| 3 | 21 |
| 4 | 29 |
以下查询结果
SELECT * FROM Table1 , Table2
| IDX | VAL | ID | POINTS |
-----------------------------
| 1 | 1val1 | 1 | 2 |
| 1 | 1val1 | 2 | 10 |
| 1 | 1val1 | 3 | 21 |
| 1 | 1val1 | 4 | 29 |
| 1 | 1val2 | 1 | 2 |
| 1 | 1val2 | 2 | 10 |
| 1 | 1val2 | 3 | 21 |
| 1 | 1val2 | 4 | 29 |
| 2 | 2val1 | 1 | 2 |
| 2 | 2val1 | 2 | 10 |
| 2 | 2val1 | 3 | 21 |
| 2 | 2val1 | 4 | 29 |
| 2 | 2val2 | 1 | 2 |
| 2 | 2val2 | 2 | 10 |
| 2 | 2val2 | 3 | 21 |
| 2 | 2val2 | 4 | 29 |
| 2 | 2val3 | 1 | 2 |
| 2 | 2val3 | 2 | 10 |
| 2 | 2val3 | 3 | 21 |
| 2 | 2val3 | 4 | 29 |
答案 2 :(得分:2)
我认为通过运行两个具有相同字段的表的示例,您会感到困惑。你指的是一个联盟,它将1个表的值与另一个表组合在一起,并使用你的例子,这将给你3 + 4 = 7个结果。
逗号分隔的FROM语句正在执行JOIN,它将遍历表X中的所有值,并将它们与表Y的所有值配对。这将导致X * Size的大小为Y的结果,并使用您的示例将是3 * 4 = 12。