这是我的表结构:
+-------+--------+----------+
| item | price | quantity |
+-------+--------+----------+
| 22452 | 579150 | 4 |
| 34664 | 334425 | 7 |
| 32249 | 204750 | 3 |
| 39970 | 97500 | 5 |
| 36907 | 116415 | 6 |
| 4338 | 207451 | 17 |
| 23425 | 388050 | 4 |
| 23427 | 532350 | 14 |
| 76080 | 180000 | 6 |
| 76076 | 400000 | 4 |
+-------+--------+----------+
项目不是唯一的,每个项目可能有1到几千行,所以我按项目分组结果。我目前的查询如下:
SELECT item AS id,
COUNT(item) as total,
ROUND(AVG(price/quantity)) AS mean,
ROUND(MIN(price/quantity)) AS cheapest
FROM `data`
GROUP BY item;
除了这4个结果,我还想计算(price/quantity)
值的最低15%行的平均价格(不是<0.15 * MAX(价格/数量),但总计0.15 *,按(价格/数量)ASC排序。我想到的解决方案涉及使用该项的计数作为限制器的临时表,但如果可能的话,我更倾向于将其作为单个查询。我确定我在这里需要一个子查询,但我不确定如何获得该特定项目的计数,然后限制该结果的15%。
使用下面的@GordonLinoff答案让我基本上都在那里。然而,我遇到了两个问题。最大的一个是@rn变量没有重置,这导致它保持增量,随后只包含第一行的项目。第二个是任何项目,其表中出现的次数的15%是&lt; 1,返回NULL。更正很小,我已经包含了我在下面使用的最终查询:
SELECT item AS id,
COUNT(item) as total,
ROUND(AVG(price/quantity)) AS mean,
ROUND(MIN(price/quantity)) AS cheapest,
ROUND(avg(case when rn <= IF(cnt * 0.15 < 1, cnt, cnt * 0.15) then price/quantity end)) as Cheapest15Percent
FROM
(SELECT d.*, cnt, IF(@item = d.item, @rn := @rn + 1, if(@item := d.item, @rn := 1, 1)) as rn
FROM `data` d LEFT JOIN
(SELECT item, COUNT(*) cnt FROM `udata` GROUP BY item) di
ON d.item = di.item CROSS JOIN
(SELECT @rn := 0, @item := -1) vars
ORDER BY d.item, d.price/d.quantity) d
GROUP BY d.item;
答案 0 :(得分:1)
这假设你想要每个项目最低15%的平均值。
以下查询枚举每个项目的行并获取总行数:
select d.*, cnt,
if(@item = item, @rn := @rn + 1, if(@item := item, 1, 1)) as rn
from `data` d left join
(select item, count(*) cnt
from data
group by item
) di
on d.item = di.item cross join
(select @rn := 0, @item := -1) vars
order by item, price/quantity;
然后,您可以基本将其插入您的查询并进行条件聚合:
SELECT item AS id,
COUNT(item) as total,
ROUND(AVG(price/quantity)) AS mean,
ROUND(MIN(price/quantity)) AS cheapest,
avg(case when rn <= cnt * 0.15 then price/quantity end) as Cheapest15Percent
FROM (select d.*, cnt,
if(@item = item, @rn := @rn + 1, if(@item := item, 1, 1)) as rn
from `data` d left join
(select item, count(*) cnt
from data
group by item
) di
on d.item = di.item cross join
(select @rn := 0, @item := -1) vars
order by item, price/quantity
) d
GROUP BY item;