经销商表
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
谷歌搜索说由于不平等加入我得到了正确的结果,但我想知道不平等加入如何工作
答案 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条符合连接条件的记录:product1
和product2
来自d1的第二条记录的部分结果集是:
| ID | Product | ID | Product |
|----|----------|----|----------|
| 1 | product2 | 1 | product1 |
| 1 | product2 | 1 | product2 |
然后查询从d1 - product3
获取下一条记录
在这种情况下,有3条符合连接条件的记录:product1
,product2
和product3
。
来自d1的第三条记录的部分结果集是:
| ID | Product | ID | Product |
|----|----------|----|----------|
| 1 | product3 | 1 | product1 |
| 1 | product3 | 1 | product2 |
| 1 | product3 | 1 | product3 |
然后查询从d1 - product4
获取最后一条记录
在这种情况下,有4条符合加入条件的记录:product1
,product2
,product3
和product4
。
来自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