我正在尝试从他们的参考手册中学习mysql。这是一个示例表。
MariaDB [menagerio]> select s1.article s1aritle, s1.dealer s1dealer,
s1.price s1price, s2.article s2article, s2.dealer s2dealer, s2.price
s2price from shop s1
left join shop s2 on s1.price < s2.price where s2.article is not null;
+----------+----------+---------+-----------+----------+---------+
| s1aritle | s1dealer | s1price | s2article | s2dealer | s2price |
+----------+----------+---------+-----------+----------+---------+
| 0003 | B | 1.45 | 0001 | A | 3.45 |
| 0003 | C | 1.69 | 0001 | A | 3.45 |
| 0003 | D | 1.25 | 0001 | A | 3.45 |
| 0001 | A | 3.45 | 0001 | B | 3.99 |
| 0003 | B | 1.45 | 0001 | B | 3.99 |
| 0003 | C | 1.69 | 0001 | B | 3.99 |
| 0003 | D | 1.25 | 0001 | B | 3.99 |
| 0001 | A | 3.45 | 0002 | A | 10.99 |
| 0001 | B | 3.99 | 0002 | A | 10.99 |
| 0003 | B | 1.45 | 0002 | A | 10.99 |
| 0003 | C | 1.69 | 0002 | A | 10.99 |
| 0003 | D | 1.25 | 0002 | A | 10.99 |
| 0003 | D | 1.25 | 0003 | B | 1.45 |
| 0003 | B | 1.45 | 0003 | C | 1.69 |
| 0003 | D | 1.25 | 0003 | C | 1.69 |
| 0001 | A | 3.45 | 0004 | D | 19.95 |
| 0001 | B | 3.99 | 0004 | D | 19.95 |
| 0002 | A | 10.99 | 0004 | D | 19.95 |
| 0003 | B | 1.45 | 0004 | D | 19.95 |
| 0003 | C | 1.69 | 0004 | D | 19.95 |
| 0003 | D | 1.25 | 0004 | D | 19.95 |
+----------+----------+---------+-----------+----------+---------+
这样的查询。
DarkSkyWeather fore = DarkSkyWeather.fromJson(response, i, timestamp, i);
Forecast_Day_Fragment fdf = new Forecast_Day_Fragment();
fdf.addItemsRecyclerForecast(fore);
我的问题是我试图加入商店桌子,比较他们的价格,但我无法理解为什么当我在主表中有7行时,这个表结果为21行。这里到底发生了什么有人可以帮我理解这个吗?
答案 0 :(得分:1)
请参阅最右侧的列,其中包含所有价格值。 基本上这里发生的是 表中价格最低的行将与表中的每个其他行匹配。价格最高的行不会与任何其他行匹配。
因此根据您的查询输出是正确的
如果不行,请使用equi-join
select s1.article s1aritle, s1.dealer s1dealer,
s1.price s1price, s2.article s2article, s2.dealer s2dealer, s2.price
s2price
from shop s1
left join shop s2 on s1.article=s2.article
where s1.price < s2.price and s2.article is not null;
答案 1 :(得分:0)
on s1.price < s2.price
将计为6 + 5 + 3 + 2 + 1
s2
表上有6个行匹配,s1.price = 1.25
时。
s2
表上有5行匹配,s1.price = 1.45
时。
s2
表上有4行匹配,s1.price = 1.69
。
s2
表上有3行匹配,s1.price = 3.45
时。
s2
表格上有2行匹配,s1.price = 3.99
。
s2
表上有一行匹配,s1.price = 10.99
。
您可以在查询命令中添加order by s1.price
,以便了解该信息。
select s1.article s1aritle, s1.dealer s1dealer,
s1.price s1price, s2.article s2article, s2.dealer s2dealer, s2.price
s2price
from shop s1
left join shop s2 on s1.price < s2.price
where s2.article is not null
ORDER BY s1.price
你可以看到我的另一个演示样本
这是另一个样本
sqlfiddle:http://sqlfiddle.com/#!9/dd04480/4
答案 2 :(得分:0)
您正在第一个表(商店)上的所有元素的连接,只有第二个表(再次购物)的元素,其价格大于第一个元素,并且它们的代码不为空(您不需要这个,因为没有带空代码的文章)所以:
文章代码0001和经销商A试图与其他所有人建立关系:
现在你必须对所有其他文章做同样的事情,看它们是否匹配。
修改强>
第一行:
0003 | B | 1.45 | 0001 | A | 3.45
商品0003,经销商B和价格1.45与商品0001,经销商A和价格3.45匹配,因为第一元素(1.45)的价格低于第二元素(3.45)的价格和第二元素的商品ID element(0001)不为null
新编辑
为什么这一行是第一行?因为您没有使用ORDER BY。在SQL中,如果不使用ORDER BY,则结果集的顺序是不可预测的,因此您获得的第一行是系统找到的与条件匹配的第一行。这个顺序取决于几个因素(你做了多少插入和删除,你以前做过什么,它在内存中有什么文件块,你做的索引等)。如果您需要订单中的结果,则必须使用ORDER BY
答案 3 :(得分:0)
这个愚蠢的查询不应该在官方参考手册中找到。
#1:可能缺少连接条件s1.article=s2.article
,否则会得到接近CROSS JOIN的爆炸结果集。当没有重复的价格时,您会将每一行与每一行以较低的价格进行比较,并在结果集中获得n*(n-1)/2
行:n=7: 7*6/2=21
。对于n=1000: 1000*999/2=499500
#2:根本不需要Left Join
,因为where s2.article is not null
无论如何都会将其变成内部加入。
预期的查询可能是:
select s1.article AS s1aritle,
s1.dealer AS s1dealer,
s1.price AS s1price,
s2.article AS s2article,
s2.dealer AS s2dealer,
s2.price AS s2price
from shop s1
join shop s2
on s1.article=s2.article
and s1.price < s2.price;
然后它返回在多个商店出售的所有商品,并将它们与价格较高的商店(不包括价格最高的商店)进行比较。