2016-03-22 5 views
0

Ich habe folgendes Schema in MySQL:Gibt es eine Möglichkeit, zwei Aggregatfunktionen in MySQL zu kombinieren, um unterschiedliche Werte zu erhalten?

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; 

ich folgendes finden müssen:

Problemstellung

Für jeden Kunden Liste speichern Details ihrer Lieblings Pizza Shop, wo ein Geschäft ist der Favorit, wenn es derjenige ist, wo die Kunden die meisten Pizzen gekauft).

Ich habe es geschafft bis die folgende Abfrage, um herauszufinden:

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

Das gibt mir ein Ergebnis wie folgt:

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

Aber in diesem Fall gibt es zwei Instanzen des gleichen Kunden (dh Homer Simpson). Warum ist das so? Ich dachte, dass ich eine Kombination von Aggregatfunktion verwenden müsste.

Jede Hilfe/Erklärung wäre großartig.

Prost!

[UPDATE 1] Just for reference:

select * from customers natürliche natürliche order_contents beitreten Aufträge kommen;

Die obige Abfrage ergibt dies:

+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+ 
| Order_ID | Mobile_Number | Name   | Age | Gender | Email   | Postcode | Timestamp   | Pizza_Name | Quantity | 
+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+ 
|  1 | 0412345678 | Homer Simpson | 38 | M  | [email protected] |  4000 | 2014-08-21 19:38:01 | Garlic Bread |  9 | 
|  1 | 0412345678 | Homer Simpson | 38 | M  | [email protected] |  4000 | 2014-08-21 19:38:01 | Hawaiian  |  9 | 
|  2 | 0412345678 | Homer Simpson | 38 | M  | [email protected] |  4000 | 2014-08-21 19:38:01 | Vegan Lovers |  1 | 
|  3 | 0412345678 | Homer Simpson | 38 | M  | [email protected] |  4502 | 2014-08-21 19:38:12 | Meat Lovers |  1 | 
|  4 | 0412345679 | Ned Flanders | 60 | M  | [email protected] |  4000 | 2014-08-21 19:39:09 | Meat Lovers |  2 | 
+----------+---------------+---------------+------+--------+-----------------+----------+---------------------+--------------+----------+ 

Auch bitte

+2

Ihr Kunde haben zwei Postleitzahl ... und Abfragegruppe durch die Postleitzahl .. das ist Ihr Problem – scaisEdge

+0

, dass der Punkt der Frage ist ...Bitte lesen Sie die Problembeschreibung – rkc88

Antwort

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 
     ) 

Dies zeigt keine Kunden an, die überhaupt keine Bestellungen getätigt haben. Wenn Sie diejenigen brauchen, ändern Sie die JOIN-stores zu einem LEFT JOIN

0

Gruppe von Ihren Kunden Primärschlüssel (vielleicht eine ID), um die Problemstellung beachten.

Der Grund, warum Sie doppelte Kunden erhalten, liegt daran, dass Sie die Abfrage nach mobile_nummer und Postleitzahl gruppieren, wodurch kein eindeutiger Index erstellt wird.

Ihre Abfrage sollte wie folgt sein:

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

ID Ersetzen Sie mit dem, was die Kunden Tabelle PK ist und es sollte Gruppe vom Kunden eindeutig.

+0

die mobile_number ist der Primärschlüssel für die Tabelle KUNDE: \ – rkc88

+0

Versuchen Sie Gruppierung durch die Telefonnummer dann –

+0

Oh und legte eine 'MAX()' Funktion auf die Summe, um nur die Route mit der höchsten Menge (die meisten Pizzen bestellt). Sollte 'MAX (SUM (Menge)) als hqty' sein. –