为什么在mysql中产生笛卡尔积?

时间:2013-09-25 15:54:43

标签: mysql sql

Table a    Table b   result
id name    id name   id name
1  a1      1  b1     1  b1
2  a2      2  b2     2  b2
3  a3                1  b1
4  a4                2  b2
                     1  b1
                     2  b2
                     1  b1
                     2  b2

当我进行此类查询时,我有两张表a和b

  

SELECT b。* FROM a as a,b AS b

,它有笛卡尔积,但我不明白,这个陈述只选择表b中的数据,但为什么

  

AS a

改变了最终结果?IMO表a与结果无关,而且无意义

4 个答案:

答案 0 :(得分:2)

如果您未在表a中指定任何列,则这是预期的行为......

SELECT a.*, b.* FROM a As a,b AS b

或更简单:

SELECT * FROM a,b

如果您寻求笛卡尔积,那么您可能想要的是什么。

修改 It defaults to select all columns from table a if I don't write a.*?It is by default?

否。您使用了SELECT b.* FROM,这意味着:向我提供来自表b的所有列。 SELECT a.*, b.*表示向我提供来自表ab的所有列。 SELECT * FROM意味着给我所有专栏,无论他们来自哪里......

答案 1 :(得分:2)

因为您没有指定链接两个表的列。你期望得到什么?如果您不想使用笛卡尔结果,请构建类似于此的查询,

SELECT b.* 
FROM a As a, b AS b
WHERE a.columnname = b.columnName

答案 2 :(得分:2)

使用别名无效。也就是说,这两个查询是相同的:

SELECT b.* FROM a AS a, b AS b
SELECT b.* FROM a, b

现在已经不在了,查询的行为符合预期:b的行为a的每一行输出一次 - 即你已经编码了一个笛卡尔积。

您的查询并不神秘。

答案 3 :(得分:2)

select子句不会过滤行。它只是projection的值。这些行在where子句中进行过滤,或者在on子句的join部分中进行过滤。

你所说的是:

  1. 获取表a的每一行和表b的每一行(from子句,生成一个笛卡儿集合)
  2. (不存在)根据谓词(whereon子句)过滤这些行
  3. 在这些结果行中,仅显示来自b表的字段。 (select条款)