MySQL总结了关系数据库中的数字

I'm making a web application to make customers order items for antyhing. For that I've made a MySQL database wich has the following tables:

  • customers
  • orders
  • order-items
  • products

In the customers table is all the information about the person such as:

  • The customer ID, for the primary key and auto increment (id)
  • The first name (first_name)
  • The last name (last_name)
  • The email adress (email_adress)
  • Information about the customer (customer_info)

Example:

enter image description here

In the orders table is all the specific information about it such as:

  • The order ID, for the primary key and auto increment (id)
  • Wich customer it ordered, linked with id field from the customers table (customer_id)
  • Order information (order_info)
  • The location where the order needs to go to (location)
  • When the order was created (created)

Example:

enter image description here

In the order-items table are all the items wich every customer ordered, this is being linked by the order-id from the previous table.

  • The ID, for primary key and auto increment, not used for any relation (id)
  • The order ID, used for wich product is for wich order. This is linked with the id field from the orders table (order_id)
  • The product ID, this is used for what product they ordered, this is linked with the id field from the products table. (product_id)
  • The amount of this product they ordered (quantity)

Example:

enter image description here

In the products table is all the information about the products:

  • The ID, for primary key and auto incrementing, This is linked with the product_id field from the order_items table (id)
  • The name of the product (name)
  • The description of the product (description)
  • The price of the product (price)

Example:

enter image description here

The problem

Bob ordered product_id 2, times 3. Wich is the sandwich with beef with the price of 2.50, wich we have to multiplie by 3 because it has been ordered 3 times. Wich is 7.50

Bob also ordered product_id 3, times 5. Wich is the sandwich with chicken with the price of 3.00, wich we have to multiplie by 5 because it has been ordered 5 times. Wich comes out on 15.00

Now i need to sum these up. wich is 15.00 + 7.50 = 22.50

The question

How do i get the product_id linked with the actual price of the product_id? wich i can then multiplie by the quantity.

And then sum up all those values with the same order_id

For the first order we get product 2 (Quantity 3) and product 3 (Quantity 5), which should add 2.50*3 + 3.00*5 = 22.50

You asked, " How do i get the product_id linked with the actual price of the product_id? Which i can then multiply by the quantity... And then sum up all those values with the same order_id."

Like this:

SELECT OI.Order_ID, Sum(OI.Quantity * P.Price) Total_Price
FROM `order-items` OI
INNER JOIN Products P
 on OI.Products_Id = P.ID
GROUP BY OI.Order_ID

Expected output for sample data in question:

ORDER_ID Total_price
1        22.50

This is why I asked about sample Output. I'm not sure what columns you were trying to return so I returned just the sum total for each order.

Now what this says Return a row for each order showing the order ID and the total_price which is the sum of (quantity ordered * price all lines for that order.

This is accomplished by looking at the order-items table (in back tic's because I'm not sure if mySQL like's dashes (-) in names.). Joining these tables based on the product_Id between the ordered items table and the price table. and then group the results by the ordered item allowing the sum to aggregate all the rows for an order times the price of the item on that line of the order together.

You can build an intermediate table that has the totals for each order, then JOIN that with the orders table to get the customerID of that order, which you join with customers to get the customer name

SELECT C.FirstName, C.LastName, Totals.Order_ID, Totals.NetCost
FROM (SELECT OI.order_id, SUM(OI.quantity * P.price) as NetCost 
        FROM orderitems as OI INNER JOIN products as P ON OI.products_id = P.id
        GROUP BY OI.order_id
    ) as Totals
    INNER JOIN orders as O on O.ID = Totals.order_id
    INNER JOIN customers as C on C.ID = O.customer_id

And the problem @xQbert is talking about is that if your customer places an order on Monday, you raise your price on Tuesday, and run this report on Wed, the report will show a total different from what the customer saw when he approved the order. A better design would be to store orderprice in orderitem, or at least the ordertotal in orders so subsequent price changes don't affect historic orders. The former is better in case a customer wants a refund on one item.

EDIT: I mean the problem @xQbert mentions in his comment, his answer came in ahead of mine but I missed it on the refresh

EDIT 2: More explanation, as requested by @Bas

It's easiest to think of this query from the inside and work outward, so let me start with getting the prices of items.
I want to link an item in orderitem with it's price, so JOIN orderitem (I give it an alias of OI) to products (I give an alias of P) on the product ID. Product ID is called products_id in OrderItem, but just ID in products.

Once I have that, I can multiply the price from Products by the quantity in OrderItems to get a cost for just that item

Because I want the total of everything for each order, I use a GROUP BY clause on this sub query, with the thing I'm grouping by being order_id. With a GROUP BY, you usually take the field or fields you are grouping by, and some "aggregate" fields where you take the sum, or max, or average, or whatever of them, and it's the sum or whatever for all rows that are in the same group.

So at this point we have defined the query inside the parenthesis. I named that Totals, and it acts just like a real table, but it goes away when your query is over.

The next step is to combine this "totals" table with your orders table so we can look up the customer ID, and then combine it with Customers so we can look up the customer name. I used aliases for Customer and Orders (C and O respectively), but they are not necessary. In fact, this could be rewritten most if not all of the aliases. I think it makes it more readable, but if they confuse you, you could use the following instead, it's the same. I think Totals is necessary, but maybe not even that.

SELECT FirstName, LastName, Totals.Order_ID, Totals.NetCost
FROM (SELECT order_id, SUM(quantity * price) as NetCost 
        FROM orderitems INNER JOIN products ON products_id = products.id
        GROUP BY order_id
    ) as Totals
    INNER JOIN orders on orders.ID = Totals.order_id
    INNER JOIN customers on customers.ID = orders.customer_id

Hopefully this is clear, but if not, leave more comments and I'll further explain tonight or tomorrow.