【问题标题】:Join one row from a table with multiple rows从具有多行的表中加入一行
【发布时间】:2012-01-20 01:03:40
【问题描述】:

这是一个关于mysql查询的问题。作为一个例子,让我们使用一个跟踪汽车销售的系统。有salespersons 的表,sales 的表和链接两者的表。大多数情况下,每笔销售只有一个人与之相关联。但有时多人与销售相关联。

Table sales
id | carId | date
---+-------+-----------
1  | 2     | 11-01-2011
2  | 8     | 11-02-2011
3  | 5     | 11-05-2011

Table link
personId | saleId
---------+-------
2        | 1 
2        | 2 
1        | 3
2        | 3

Table salesperson
id | name  | age
---+-------+----
1  | Barry | 25
2  | Sara  | 32

要检索数据,我想在网页中显示每次销售的信息。但是,当多人与销售相关联时,就会出现问题。我尝试在我的代码中应用下面的查询,之后 PHP 会处理多人与一次销售相关联的异常,但由于销售表的长度,下面的查询需要太多时间来运行:

SELECT count(personId) as amount, carId, date
FROM link 
JOIN salesperson ON link.personId = salesperson.id  
JOIN sales ON sales.id = link.saleId
GROUP BY link.saleId

有没有更高效的查询可以使用?顺便说一下,表的索引已经完成。

【问题讨论】:

  • 您要检索哪些数据?是每个销售员的销售额吗?
  • 我想显示关联销售人员的销售列表
  • 你在链接中使用过任何索引吗??
  • 是的,一个在 personID 上,一个在 saleID 上
  • 我会加倍 ChrisBD,然后重新询问您要检索的内容。如果按 saleid 分组,那么销售人员的 nameage 就没有意义了。

标签: mysql optimization count query-optimization


【解决方案1】:

那么就是:

SELECT STRAIGHT_JOIN
    amount, carId, date
FROM (
    SELECT saleId, count(*) as amount
    FROM link
    GROUP BY saleId
    ORDER BY NULL) as amounts
JOIN sales ON sales.id = amounts.saleId;

【讨论】:

    【解决方案2】:

    如果您关心性能方面,请避免使用连接,尤其是在 mysql 中。 阅读这篇展示高效编码技术的文章 http://phpadvent.org/2011/a-stitch-in-time-saves-nine-by-paul-jones

    对于您在第一次查询中遇到的问题,请选择销售 ID 在第二个查询中从链接表中选择 personID 在第三个查询中选择从人员表中选择所有人员

    正如文章中提到的,在传递查询时使用 IN 子句。它在编码中看起来并不冗长,但比在具有 15k+ 行的表上使用连接效率更高

    【讨论】:

      【解决方案3】:

      我认为问题可能是您使用链接表作为基表并且查询的数据库优化不好。 试试:

      SELECT count(sp.personId) as amount, s.carId as carId, s.date as date, sp.name as name, sp.age as age  
      FROM sales as s
      JOIN link as l ON s.id = l.saleId
      JOIN salesperson as sp ON l.personId = sp.id  
      ORDER BY l.saleId
      

      【讨论】:

      • 这将统计产品中的行数并输出第一行 =)
      【解决方案4】:

      您的查询看起来不错,但您的 group by 有点奇怪...
      尝试按所有非聚合列分组的标准方法,如下所示:

      SELECT carId, date, name, age, count(personId) as amount
      FROM link 
      JOIN salesperson ON salesperson.id = link.personId
      JOIN sales ON sales.id = link.saleId
      GROUP BY 1,2,3,4;
      

      【讨论】:

      • 我从未听说过'GROUP BY 1,2,3,4;'但查询需要 28 秒
      • GROUP BY 1,2,3,4 是“按列 #1、列 #2、列 #3、列 #4 分组”的缩写,在这种情况下与编码 GROUP BY carId, date, name, age 相同。我更喜欢这种语法的简洁性。
      【解决方案5】:

      您是否为表格设置了正确的索引?我不知道你的桌子有多大,但我无法想象这应该是个大问题。

      另外,您想从查询中得到什么结果?您似乎在尝试获取所有销售额,然后计算参与的销售人员数量?

      【讨论】:

      • 没有与销售人员的所有销售。表格链接超过 350.000 行
      • 你把索引放在桌子上了吗(你确定你做得对吗)?你用什么类型的列?
      猜你喜欢
      • 2018-03-25
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 2011-11-02
      相关资源
      最近更新 更多