4

所以我试图计算我系统中每家餐厅的重复订单数量。这被定义为从该餐厅多次订购的用户数量(基于他们的电子邮件地址 eo_email)。架构下的示例

这是代表我的餐厅的表格

CREATE TABLE IF NOT EXISTS `lf_restaurants` (
  `r_id` int(8) NOT NULL AUTO_INCREMENT,
  `r_name` varchar(128) DEFAULT NOT NULL,
  PRIMARY KEY (`r_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

INSERT INTO `lf_restaurants` (`eo_id`, `eo_ref_id`) VALUES
('1', 'Restaurant X'),
('2', 'Cafe Y');

这是我的订单表

CREATE TABLE IF NOT EXISTS `ecom_orders` (
  `eo_id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `eo_ref_id` varchar(12) DEFAULT NOT NULL,
  `eo_email` varchar(255) DEFAULT NOT NULL,
  `eo_order_parent` int(11) NOT NULL,
  PRIMARY KEY (`eo_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ;

INSERT INTO `ecom_orders` (`eo_id`, `eo_ref_id`, `eo_email`, `eo_order_parent`) VALUES
('', '', 'a@a.com', '1'),
('', '', 'a@a.com', '1'),
('', '', 'a@a.com', '1'),
('', '', 'a@a.com', '1'),
('', '', 'a@a.com', '1'),
('', '', 'b@b.com', '1'),
('', '', 'b@b.com', '1'),
('', '', 'c@c.com', '1'),
('', '', 'd@d.com', '1'),
('', '', 'e@e.com', '1'),
('', '', 'a@a.com', '2'),
('', '', 'c@c.com', '2'),
('', '', 'c@c.com', '2'),
('', '', 'e@e.com', '2');

所以餐厅 X (r_id 1) 有 10 个订单。用户 a@a.com 和 b@b.com 曾多次从该餐厅点过餐,而 c@c.com、d@d.com 和 e@e.com 仅点过一次,因此需要退货40%

Cafe Y (r_id 2) 有 4 个订单。用户 c@c.com 已下单两次,用户 a@a.com 和 e@e.com 仅下单一次,因此需要退货 33%

我不确定发布我已经得到的东西会很好,因为我一直遇到“子查询有超过 1 个结果”,或者如果我将该子查询包装在它自己的虚拟查询中并带有一个计数,它不会让我使用我的字段需要来自主查询,例如 r_id。但这里有:

SELECT r_name,
    (SELECT COUNT(*) AS cnt_users
        FROM (
            SELECT *
            FROM ecom_orders
            WHERE eo_order_parent = r_id
            GROUP BY eo_email
        ) AS cnt_dummy
    ) AS num_orders,
    (SELECT COUNT(*) AS cnt
        FROM ecom_orders
        WHERE eo_order_parent = r_id
        GROUP BY eo_order_parent, eo_email

    ) AS num_rep_orders
    FROM lf_restaurants
    ORDER BY num_orders DESC

num_orders 子查询说它不识别 r_id,因为我猜这是由于执行事物的顺序

num_rep_orders 子查询以多行的形式返回,但我真的希望它只返回一个值,如果我像 num_orders 子查询那样做,我可以这样做,但随后会遇到 r_id 不存在问题。

所以我的问题是:如何在不遇到子查询的情况下获得我需要的这些值有超过 1 行,并且 r_id 不存在?

然后从这两个值中,我可以计算出百分比,所有这些都应该是肉汁:) 非常感谢任何帮助!

4

2 回答 2

2

所以餐厅 X (r_id 1) 有 10 个订单。用户 a@a.com 和 b@b.com 曾多次从该餐厅点过餐,而 c@c.com、d@d.com 和 e@e.com 仅点过一次,因此需要退货40%

Cafe Y (r_id 2) 有 4 个订单。用户 c@c.com 已下单两次,用户 a@a.com 和 e@e.com 仅下单一次,因此需要退货 33%

好的。因此,让我们从获取回头客的数量开始。

SELECT eo_order_parent, eo_email, COUNT(eo_email) AS orders FROM ecom_orders
    GROUP BY eo_order_parent, eo_email
    HAVING orders > 1;

以及不同客户的总数

SELECT eo_order_parent, COUNT(eo_email) FROM ecom_orders
    GROUP BY eo_order_parent;

但是我们可以一口气做到这一点:

SELECT eo_order_parent,
    SUM(CASE WHEN orders > 1 THEN 1 ELSE 0 END) AS repeats,
    SUM(1) AS total FROM
    (
        SELECT eo_order_parent, eo_email, COUNT(*) AS orders FROM ecom_orders
            GROUP BY eo_order_parent, eo_email
    ) AS eo_group_1
GROUP BY eo_order_parent;

这给出了:

+-----------------+---------+-------+
| eo_order_parent | repeats | total |
+-----------------+---------+-------+
|               1 |       2 |     5 |
|               2 |       1 |     3 |
+-----------------+---------+-------+
2 rows in set (0.00 sec)

那么2/5就是你的40%,1/3就是33%。

于 2012-09-12T13:43:34.043 回答
1

以下查询计算回头客数和每家餐厅的总客户数

SELECT
  u.r_id,
  u.r_name,
  SUM(u.no_orders > 1) AS repeats,
  SUM(u.no_orders) AS orders,
  COUNT(u.eo_email) AS customers
FROM (
    SELECT
      r.*,
      o.eo_email,
      COUNT(o.eo_id) AS no_orders
    FROM lf_restaurants r
    LEFT JOIN ecom_orders o ON o.eo_order_parent = r.r_id
    GROUP BY o.eo_email
) u
GROUP BY
  r.r_id;

子查询首先计算每个客户/餐厅对的订单数。外部查询由此计算顾客数量、回头客数量和每家餐厅的顾客总数。您还可以计算百分比(但这不必在查询中完成)。

于 2012-09-12T13:55:56.457 回答