【问题标题】:MySQL: Average OF Subquerys (NOT in the FROM/GROUP BY)MySQL:平均子查询(不在 FROM/GROUP BY 中)
【发布时间】:2015-02-15 22:37:06
【问题描述】:

我想显示我的数据库中产品组的平均价格。因此,我想返回该产品组内所有产品的平均价格。

首先,我想知道该组有多少价格变化。此查询成功返回所有日期,并带有此查询...

SELECT DISTINCT(DATE(gbp.prdate)) as dte
FROM sku AS s
  INNER JOIN mt_price gbp ON s.id = gbp.
WHERE (gbp.prdate < NOW() - INTERVAL ? DAY) AND (s.grp = ?)`

然后我在 php 中使用 foreach 生成以下查询...

$i = 1;
$qry = "SELECT s.id AS sid, s.sku, s.title AS s_title,";
foreach ($dates as $date) {
  $qry .= "(SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE(?) ORDER BY prdate LIMIT 1) AS ?, ";
  $datearr[] = $date;
}
$qry = substr($qry, 0, -2) . " ";
$qry .= "FROM sku AS s
  WHERE (s.grp = ?)
  GROUP BY s.id
  ORDER BY s.id";
$results = $db->prepare($qry);
foreach($datearr as $darr) {
  $results->bindParam($i++,$darr->dte,PDO::PARAM_STR);
  $results->bindParam($i++,$darr->dte,PDO::PARAM_STR);
}

上面的一个例子给了我这个查询......

SELECT s.id AS sid, s.rid, s.sku, s.title AS s_title,
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-01-08') ORDER BY prdate LIMIT 1) AS '2015-01-08',
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-02-12') ORDER BY prdate LIMIT 1) AS '2015-02-12',
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-01-26') ORDER BY prdate LIMIT 1) AS '2015-01-26',
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-02-08') ORDER BY prdate LIMIT 1) AS '2015-02-08',
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-01-30') ORDER BY prdate LIMIT 1) AS '2015-01-30',
  (SELECT price FROM price WHERE price.sid = s.id AND prdate <= DATE('2015-02-02') ORDER BY prdate LIMIT 1) AS '2015-02-02'

来自 sku AS s 哪里(s.cat = 'TLPT01') 按 s.id 分组 按 s.id 订购

当我按上述方式运行此查询时,我得到了我所期望的结果,每个 SKU 只有一个价格(低至LIMIT)和正确的价格。然后它将随着DATE 的变化正确显示 SKU 的价格。耶!

所以,我想要得到所有这些结果的平均值。如果我在s.id 前面使用AVG,我会得到SKU 的平均值,这显然不是一个有意义的结果。我想要返回的所有 SKU 的平均价格(因此,GROUP BY 应该只给我一行信息)。当我将GROUP BY 放在子查询之前时,我得到了一个错误。

【问题讨论】:

  • 请在$qry 在循环中建立完整的SQL 字符串后发布它,因为很难看到它变成了什么。此外,发布相关表中的输入行示例,以及您期望查询输出的示例。在 PHP 代码之外并完全脱离 PHP 代码开发查询非常重要。在没有所有 PHP 代码和参数绑定的情况下,开发和调试查询会容易得多。
  • 谢谢迈克尔,我已经编辑了我的帖子。
  • 请注意,DISTINCT 不是函数。

标签: mysql average


【解决方案1】:

尝试如下进行子查询 (SELECT AVG(price) FROM price WHERE price.sid = s.id AND prdate

【讨论】:

  • 我试过这个,它给出了该 SKU 持续时间内的平均价格。我完成PHP foreach 的原因是我想要当时的价格列(因此有多个子查询),然后返回该列(以及所有其他列)的平均值。
【解决方案2】:

我发现将子查询移动到LEFT JOIN 解决方案。然后我可以对从这些 JOIN 返回的价格执行AVG。我仍然不知道为什么我不能只 AVG 子查询,但是这种方法(虽然不是超级快)...有效。

SELECT s.cat, s.id AS sid, s.rid, s.sku, s.title AS s_title, AVG(pr1.price)
FROM sku AS s
  LEFT JOIN (SELECT sid, price, prdate FROM price WHERE prdate <= DATE('2014-12-21') ) AS pr1 ON s.id = pr1.sid
  ... <more from foreach, add more AVG on top line> ...
WHERE (s.cat = 'TLPT01')
GROUP BY cat

【讨论】:

    【解决方案3】:

    你不是在编码你所说的; 每个日期的平均值。在子查询上使用平均查询(简化):

    select date, avg(avg_price) from (
        select group_id, date, avg(price) avg_price
        from mytable
        group by group_id, date
    ) x
    group by date
    

    内部查询将为每个 group_id 和日期生成一个 avg 值,而外部查询仅按日期平均这些 group_id/date 值。

    【讨论】:

    • 虽然准确地说这是日期平均值,而不是组的平均值。例如。如果一个日期有 1 个值,而另一个日期有 3 个值,则外部平均值只会平均 2 个值(第一个日期和第二个日期)。这是否重要取决于所需的准确度级别和值的范围。
    • 我认为我的问题(已经晚了!)没有正确提出。我已经编辑了我的问题。我想要每个日期的平均价格,所以每个子查询。
    • @themrflibble 我将缩写任务更改为按日期平均 - 这有帮助吗?你能用这个想法试试你的代码吗?
    猜你喜欢
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多