有没有办法在MySQL中组合两个聚合函数来获取不同的值?

时间:2016-03-22 07:03:54

标签: mysql sql group-by aggregate-functions

我在MySQL中有以下架构:

CREATE TABLE `ORDER_CONTENTS` (
  `Order_ID` int(10) NOT NULL,
  `Pizza_Name` varchar(20) NOT NULL DEFAULT '',
  `Quantity` int(2) NOT NULL,
  PRIMARY KEY (`Order_ID`,`Pizza_Name`),
  KEY `ordercontentsfk2_idx` (`Pizza_Name`),
  CONSTRAINT `order_contentsfk1` FOREIGN KEY (`Order_ID`) REFERENCES `ORDERS` (`Order_ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `CUSTOMERS` (
  `Mobile_Number` varchar(10) NOT NULL,
  `Name` varchar(45) NOT NULL,
  `Age` int(3) DEFAULT NULL,
  `Gender` enum('M','F') DEFAULT NULL,
  `Email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`Mobile_Number`),
  UNIQUE KEY `Mobile_Number_UNIQUE` (`Mobile_Number`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ORDERS` (
  `Order_ID` int(10) NOT NULL AUTO_INCREMENT,
  `Mobile_Number` varchar(10) NOT NULL,
  `Postcode` int(4) NOT NULL,
  `Timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`Order_ID`),
  KEY `ordersfk1_idx` (`Mobile_Number`),
  KEY `ordersfk2_idx` (`Postcode`),
  CONSTRAINT `ordersfk1` FOREIGN KEY (`Mobile_Number`) REFERENCES `CUSTOMERS` (`Mobile_Number`) ON DELETE NO ACTION ON UPDATE CASCADE,
  CONSTRAINT `ordersfk2` FOREIGN KEY (`Postcode`) REFERENCES `STORES` (`Postcode`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

CREATE TABLE `STORES` (
  `Postcode` int(4) NOT NULL DEFAULT '0',
  `Address` varchar(100) DEFAULT NULL,
  `Phone_Number` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`Postcode`),
  UNIQUE KEY `Postcode_UNIQUE` (`Postcode`),
  UNIQUE KEY `Address_UNIQUE` (`Address`),
  UNIQUE KEY `Phone_Number_UNIQUE` (`Phone_Number`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我需要找到以下内容:

问题陈述

  

为每位客户列出他们最喜欢的披萨的商店详情   商店,如果商店是最喜欢的商店   顾客购买了最多的比萨饼。)

我已经设法解决了以下问题:

select `Name`,SUM(quantity) as hqty,COUNT(*),Postcode from CUSTOMERS natural join orders natural join order_contents group by Mobile_Number,postcode;

这给我一个结果如下:

+---------------+------+----------+----------+
| Name          | hqty | COUNT(*) | Postcode |
+---------------+------+----------+----------+
| Homer Simpson |   19 |        3 |     4000 |
| Homer Simpson |    1 |        1 |     4502 |
| Ned Flanders  |    2 |        1 |     4000 |
+---------------+------+----------+----------+

但在这种情况下,同一客户有两个实例(即Homer Simpson)。为什么会这样?我想我需要使用聚合函数的组合。

任何帮助/解释都会很棒。

干杯!

[更新1] 仅供参考:

  

从CUSTOMERS中选择*自然连接顺序自然连接   order_contents;

以上查询产生了这个:

+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+
| Order_ID | Mobile_Number | Name          | Age  | Gender | Email           | Postcode | Timestamp           | Pizza_Name   | Quantity |
+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+
|        1 | 0412345678    | Homer Simpson |   38 | M      | homer@doh.com   |     4000 | 2014-08-21 19:38:01 | Garlic Bread |        9 |
|        1 | 0412345678    | Homer Simpson |   38 | M      | homer@doh.com   |     4000 | 2014-08-21 19:38:01 | Hawaiian     |        9 |
|        2 | 0412345678    | Homer Simpson |   38 | M      | homer@doh.com   |     4000 | 2014-08-21 19:38:01 | Vegan Lovers |        1 |
|        3 | 0412345678    | Homer Simpson |   38 | M      | homer@doh.com   |     4502 | 2014-08-21 19:38:12 | Meat Lovers  |        1 |
|        4 | 0412345679    | Ned Flanders  |   60 | M      | ned@vatican.net |     4000 | 2014-08-21 19:39:09 | Meat Lovers  |        2 |
+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+

另外请注意问题陈述

2 个答案:

答案 0 :(得分:0)

按客户主键分组(可能是ID)。

您获得重复客户的原因是您通过mobile_number和邮政编码对查询进行分组,而后者没有制作唯一索引。

您的查询应该是这样的:

select Name ,SUM(quantity) as hqty,COUNT(*),Postcode from CUSTOMERS natural join orders natural join order_contents group by CUSTOMERS.id

将ID替换为客户表PK的任何内容,并且应该由客户唯一地进行分组。

答案 1 :(得分:0)

SELECT  *
FROM    customers c
JOIN    stores s
ON      s.postcode =
        (
        SELECT  postcode
        FROM    orders o
        JOIN    order_contents oc
        USING   (order_id)
        WHERE   o.mobile_number = c.mobile_number
        GROUP BY
                postcode
        ORDER BY
                SUM(quantity) DESC
        LIMIT 1
        )

这不会显示根本没有订单的客户。如果您需要,请将JOIN更改为storesLEFT JOIN