【问题标题】:How to calculate Average services ordered per order with unique reference by user? (MySQL)如何计算用户唯一参考的每个订单订购的平均服务? (MySQL)
【发布时间】:2019-09-23 10:03:35
【问题描述】:

我认为我的问题更多是关于数学而不是 MySQL。

已下订单可以属于三种可能的服务之一(例如 A、B、C)。用户有前。 100 个已下订单(例如,服务 A 的 30 个、服务 B 的 40 个和服务 C 的 30 个)。并且下单有属性引用(有些订单属于同一个属性引用,有些不是)。

我需要为一位特定用户计算“每个列表订购的平均服务计数(唯一属性参考)”。该值介于 0 到 3 之间(例如 1.4)。

例如,如果用户为“Property X”订购了 3 个订单(并且没有订购其他属性)参考,这是服务 A、服务 A 和服务 C 的订单 - 平均值将为 2(他订购了 2 个服务类型对于相同的属性参考)。

样本数据:

CREATE TABLE IF NOT EXISTS `orders` (
`id` int(6) NOT NULL,
`user_id` int(6) NOT NULL,
`reference` varchar(64) NOT NULL,
`service_type` varchar(16) NOT NULL
);
INSERT INTO `orders` (`id`, `user_id`, `reference`, `service_type`) VALUES
('4', '66', 'Blue house',  'serviceA'),
('2', '66', 'Blue house',  'serviceB'),
('5', '66', 'Blue house',  'serviceB'),
('6', '66', 'Blue house',  'serviceC'),
('1', '66', 'Red house',   'serviceA'),
('3', '66', 'Red house',   'serviceA'),
('7', '66', 'Green house', 'serviceC')

在此示例中: 用户订购了 3 项独特的服务作为“蓝屋”参考,1 项独特的服务 用于“红房子”和 1 项独特的“温室”参考服务。 我需要知道每个唯一列表的平均订购服务数量 (不是每个列表的平均值,所有这些数据只有一个值)。 所以我们在这里为用户提供了 3 个独特的参考(蓝色、红色、绿色房屋)并且知道如何 每个参考都分配了许多独特的服务。如何取平均值?

我需要从计算中得到的预期输出: 一个值,例如 1.7(我不知道这个示例的实际值,因为我不知道如何进行数学计算)。这意味着用户在所有订单的所有期间平均订购了 1.7 个(来自 3 个可用的)服务以获取唯一属性参考。

我可以毫无问题地获得用户总订单,具有唯一属性引用的用户总订单,但我不明白如何在不使用 PHP 进行大量请求和数学计算的情况下计算出我需要的东西。

例如获取具有唯一订单参考的订单计数(在我下面的示例中为 3):

SELECT COUNT(distinct reference) as total_orders FROM orders WHERE user_id = 66;

但我不明白接下来要做什么。

样本数据: http://sqlfiddle.com/#!9/dd00d7

【问题讨论】:

  • 我不清楚每个列表是什么以及唯一的属性参考是什么,因为这些都没有出现在订单表定义中。您可以通过将示例数据和预期输出作为文本添加到问题中来改进此问题。
  • 假设用户有 10 个已下订单(3、3 和 4)。见:Why should I provide an MCRE for what seems to me to be a very simple SQL query?
  • @P.Salmon 如果这个任务可以通过 MySQL 请求来完成——我需要原始的 MySQL 请求。如果在请求后需要额外的数学检查,我需要 MySQL+PHP 或 MySQL+Math 解释我需要做什么。添加了示例数据。
  • (I don't know real value from this example, because I don't know how to calculate this mathematically) ??如果您不知道,我不确定我们能否帮助您。
  • 首先你要明确你想要什么结果?只有这样我们才能帮助您...

标签: mysql sql math aggregate-functions


【解决方案1】:

如果我理解正确,您需要两个级别的GROUP BY。在内部级别,您需要每个列表的不同服务数量(蓝色房屋 = 3,红色房屋 = 1,绿色 = 1)。在外层,您计算 3、1、1 的平均值:

SELECT userid, AVG(service_type_count) AS avg_service_type_per_listing
FROM (
    SELECT userid, reference, COUNT(DISTINCT service_type) AS service_type_count
    FROM orders
    GROUP BY userid, reference
) AS x
GROUP BY userid

【讨论】:

  • 谢谢,看来这正是我要找的!简短、优雅和专业的解决方案!
【解决方案2】:

这是一个猜测,子查询通过用户和引用识别不同的服务,而外部查询计算出平均值。

drop table if exists t;

CREATE TABLE t (
  `id` int(6) NOT NULL,
  `userid` int(6) NOT NULL,
  `reference` varchar(64) NOT NULL,
  `service_type` varchar(16) NOT NULL
);
INSERT INTO t (`id`, `userid`, `reference`, `service_type`) VALUES
  ('1', '66', 'Red house', 'serviceA'),
  ('2', '66', 'Blue house', 'serviceB'),
  ('3', '66', 'Red house', 'serviceA'),
  ('4', '66', 'Blue house', 'serviceA'),
  ('5', '66', 'Blue house', 'serviceB'),
  ('6', '66', 'Blue house', 'serviceC'),
  ('7', '66', 'Green house', 'serviceC');

select s.userid,
        sum(s.distinctservice_types) distinctservice_types,
        sum(s.distinctservice_types) / 3 avgs
from
(
select userid,reference,count(Service_type) countservice_types,
         count(distinct service_type) distinctservice_types
from t
group by userid,reference
) s
group by s.userid
;

+--------+-----------------------+--------+
| userid | distinctservice_types | avgs   |
+--------+-----------------------+--------+
|     66 |                     5 | 1.6667 |
+--------+-----------------------+--------+
1 row in set (0.00 sec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多