从mysql参考手册中了解Mysql查询

时间:2018-04-22 08:43:38

标签: mysql sql

我正在尝试从他们的参考手册中学习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行。这里到底发生了什么有人可以帮我理解这个吗?

4 个答案:

答案 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

  1. s2表上有6个行匹配,s1.price = 1.25时。

  2. s2表上有5行匹配,s1.price = 1.45时。

  3. s2表上有4行匹配,s1.price = 1.69

  4. s2表上有3行匹配,s1.price = 3.45时。

  5. s2表格上有2行匹配,s1.price = 3.99

  6. s2表上有一行匹配,s1.price = 10.99

  7. 您可以在查询命令中添加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试图与其他所有人建立关系:

  1. 由于价格相等(它可能会更少),因此本身不匹配
  2. 凭借0001和经销商B匹配,因为价格较低,所以排成一行
  3. 凭借0002和经销商A匹配,因为价格较低且排成一排
  4. 有了0003和经销商B,因为价格较高,所以不会算数学。没有排成一行
  5. 使用0003和经销商C和D与第4号相同
  6. 对于第0004条和经销商D,由于价格较低,它会排成一排。
  7. 现在你必须对所有其他文章做同样的事情,看它们是否匹配。

    修改

    第一行:

    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;

然后它返回在多个商店出售的所有商品,并将它们与价格较高的商店(不包括价格最高的商店)进行比较。