什么是不平等加入mysql,它是如何工作的

时间:2016-01-30 13:33:06

标签: mysql sql

经销商表

ID | Product
------------
1   product1
1   product2
1   product3
1   product4
2   product1
2   product2
2   product3
3   product1
3   product2
3   product3
4   product1
4   product2

我想找到所有id及其前2个产品

我的尝试是

  select d1.id,d1.product,count(d1.product)
  from dealer d1 join
       dealer d2  
       on d1.id=d2.id
  where d1.product>=d2.product
  group by d1.id,d1.product
 having count(d1.product)<=2

我的结果是

id |product   |count(d1.product) 
----------------------------
1   product1    1
1   product2    2
2   product1    1
2   product2    2
3   product1    1
3   product2    2
4   product1    1
4   product2    2
谷歌搜索说由于不平等加入我得到了正确的结果,但我想知道不平等加入如何工作

1 个答案:

答案 0 :(得分:4)

要了解它是如何工作的,只需逐步调试查询,但使用较小的数据集 - 例如仅适用于id = 1的行

select * from dealer;

| ID |  Product |
|----|----------|
|  1 | product1 |
|  1 | product2 |
|  1 | product3 |
|  1 | product4 |

查询的第一个评估部分是连接:

select *
from dealer d1 
join dealer d2  
on d1.id=d2.id AND d1.product>=d2.product
order by 1,2,3,4

加入如何运作?
它从左表(d1)获取第一个记录,然后搜索右表(d2)并从右表中选择满足连接条件的所有记录。

对于product1(d1表)的记录,d2表中只有一条满足条件的记录:d1.product>=d2.product - 只有product1
因此,来自d1的第一条记录的部分结果集是:

| ID |  Product | ID |  Product |
|----|----------|----|----------|
|  1 | product1 |  1 | product1 |

然后查询从d1 - product2获取下一条记录 在这种情况下,有2条符合连接条件的记录:product1product2 来自d1的第二条记录的部分结果集是:

| ID |  Product | ID |  Product |
|----|----------|----|----------|
|  1 | product2 |  1 | product1 |
|  1 | product2 |  1 | product2 |

然后查询从d1 - product3获取下一条记录 在这种情况下,有3条符合连接条件的记录:product1product2product3
来自d1的第三条记录的部分结果集是:

| ID |  Product | ID |  Product |
|----|----------|----|----------|
|  1 | product3 |  1 | product1 |
|  1 | product3 |  1 | product2 |
|  1 | product3 |  1 | product3 |

然后查询从d1 - product4获取最后一条记录 在这种情况下,有4条符合加入条件的记录:product1product2product3product4
来自d1的第4条记录的部分结果集是:

| ID |  Product | ID |  Product |
|----|----------|----|----------|
|  1 | product4 |  1 | product1 |
|  1 | product4 |  1 | product2 |
|  1 | product4 |  1 | product3 |
|  1 | product4 |  1 | product4 |

查询的整个结果集是:

| ID |  Product | ID |  Product |
|----|----------|----|----------|
|  1 | product1 |  1 | product1 |
|  1 | product2 |  1 | product1 |
|  1 | product2 |  1 | product2 |
|  1 | product3 |  1 | product1 |
|  1 | product3 |  1 | product2 |
|  1 | product3 |  1 | product3 |
|  1 | product4 |  1 | product1 |
|  1 | product4 |  1 | product2 |
|  1 | product4 |  1 | product3 |
|  1 | product4 |  1 | product4 |

接下来,让GROUP BY子句应用于上面的结果集:

select d1.id,d1.product,count(d1.product)
from dealer d1 
join dealer d2  
on d1.id=d2.id AND d1.product>=d2.product
group by d1.id,d1.product;

| ID |  Product | count(d1.product) |
|----|----------|-------------------|
|  1 | product1 |                 1 |
|  1 | product2 |                 2 |
|  1 | product3 |                 3 |
|  1 | product4 |                 4 |

最后一步是应用HAVING count(..)&lt; = 2从上述结果集中过滤掉所有带有count&gt;的记录。 2

select d1.id,d1.product,count(d1.product)
from dealer d1 
join dealer d2  
on d1.id=d2.id AND d1.product>=d2.product
group by d1.id,d1.product
having count(d1.product)<=2;

| ID |  Product | count(d1.product) |
|----|----------|-------------------|
|  1 | product1 |                 1 |
|  1 | product2 |                 2 |

我希望现在应该清楚它是如何运作的 以上所有步骤均包含在此演示中:http://sqlfiddle.com/#!9/e4890/7