Getting SUM based on quantity in MySQL? - php

I have this tables
ORDERS
orders_id
order_article_id
order_invoice_id
order_customer_id
order_qty
ARTICLES
articles_id
article_name
article_qty
article_price
article_amount
CUSTOMERS
customers_id
customer_name
customer_position
customer_office
And SQL Join Table
$sql="SELECT customer_name, article_name, orders_id FROM orders
LEFT JOIN articles ON order_article_id = articles_id
LEFT JOIN customers on order_customer_id = customers_id";
From this query I need to get AMOUNT.
Amount is example
USER: MICHAEL
AMOUNT: ORDER ID = order_article_id + order_qty;
Is it possible to do that in MySQL or i need some addition PHP code?

You can do it in MySQL, using a GROUP BY query and a SUM() aggregate function:
SELECT
c.customer_name,
SUM(a.article_price*a.article_quantity) AS amount
FROM
orders o LEFT JOIN articles a
ON o.order_article_id = a.articles_id
LEFT JOIN customers c
ON o.order_customer_id = c.customers_id
GROUP BY
c.customers_id,
c.customer_name
you might want to obtain the AMOUNT per order, then you need to group by also for the order_id:
GROUP BY
o.orders_id,
c.customers_id,
c.customer_name

Related

How to increase the speed of MySQL query with extra condition?

I'm trying to speed up the following query as it takes quite long to run: now it's 'only' about 1.5 seconds, but it will certainly get slower with more rows (which will 10x over the next period).
Basically, I want to show all the rows from the orders table for the user, and per row show the total order amount (which is the SUM of the orders_products table).
SELECT
orders.order_number,
orders.order_date,
companies.company_name,
COALESCE(SUM(orders_products.product_price * orders_products.product_quantity),0) AS order_value
FROM orders
LEFT JOIN companies ON companies.id = orders.company_id
LEFT JOIN orders_products ON orders_products.order_id = orders.id
LEFT JOIN users ON users.id = orders.user_id
WHERE orders.user_id = '$user_id'
AND companies.user_id = '$user_id'
GROUP BY orders.id ORDER BY orders.order_date DESC, orders.order_number DESC
I've tried adding another condition AND orders_products.user_id = '$user_id'. Speed wise the query was about 12x faster (yeah!) but the problem is that not all orders have products in them. In this case, the orders without products in them are not returned.
How do I change my query so that despite of an order not having products in them, it still is returned (with total order value 0), whilst also speeding up the query?
Thank you in advance for your help!
You might find it faster to use a correlated subquery:
SELECT o.order_number, o.order_date, c.company_name,
(SELECT COALESCE(SUM(op.product_price * op.product_quantity), 0)
FROM orders_products op
WHERE op.order_id = o.id
) AS order_value
FROM orders o LEFT JOIN
companies c
ON c.id = o.company_id AND c.user_id = o.user_id
WHERE o.user_id = '$user_id'
ORDER BY o.order_date DESC, o.order_number DESC
This gets rid of the outer aggregation which is often a performance win.
Then for performance you want the following indexes:
orders(user_id, order_date desc, order_number_desc, company_id)
companies(id, company_id, company_name)
orders_products(order_id, product_price, product_quantity)

Counting values from two tables and returning the result in a single value

How to count value from two tables and return the result in a single value.?
I had two tables named order and affiliate, like below:
order:
order_ID(primary key), order_name, Order_status, affiliate_ID (foreign key)
affiliate:
affiliate_ID (primary key),affiliate_name
Now, I want to count the orders based on affiliate name by comparing the affiliate_ID on order table and affiliate table.
I have tried it like this:
Query
SELECT COUNT(*)
FROM order o
AND (SELECT COUNT (affiliate_name) FROM affiliate a
WHERE a.affiliate_id = O.affilate_id) AS total
It returns an error.
I feel this is what you need
SELECT a.affiliate_ID, a.affiliate_name, COUNT(o.order_ID) as total
FROM order o
LEFT JOIN affiliate a ON o.affiliate_ID = a.affiliate_ID
GROUP BY o.affiliate_ID;
to add WHERE clause, see sample
SELECT a.affiliate_ID, a.affiliate_name, COUNT(o.order_ID) as total
FROM order o
LEFT JOIN affiliate a ON o.affiliate_ID = a.affiliate_ID
WHERE o.affiliate_ID = 3
GROUP BY o.affiliate_ID;
Not sure I understand your question correctly, but is this what you're looking for ?
SELECT *, COUNT(*) as total
FROM order o
JOIN affiliate a ON a.affiliate_id = o.affiliate_id
GROUP BY o.affiliate_id
Otherwise, provive sample & desired result example please.

GROUP BY query displays only one row associated with date in html table

I tried a query to show items of same date in my table with different rows but date should be displayed only once. Something like this.
Date: 15-09-2015
ItemId:1 quantity:6 size:XL
ItemId:1 quantity:4 size:Small
ItemId:2 quantity:6 size:XL
Date: 16-09-2015
ItemId:3 quantity:9 size:XL
ItemId:1 quantity:4 size:Small
ItemId:2 quantity:6 size:XL
I tried the following query. It just returns me only one row for each date.
SELECT orders.date, order_detail.quantity, order_detail.price, order_detail.color, order_detail.size, customers.name, products.product_name, products.product_image FROM order_detail JOIN orders ON orders.serial=order_detail.orderid JOIN customers ON customers.serial=orders.customerid JOIN products ON products.productid=order_detail.productid WHERE customers.email='abc#yahoo.com' GROUP BY orders.date ORDER BY orders.date
Any suggestions please. How can i display like this in my html table.
Group by looks for an aggregate function i.e. sum('field_name'). You will need to get the distinct values for the order.date then subquery (not sure the parentheses are in the right spot).
SELECT DISTINCT orders.date, (SELECT order_detail.quantity, order_detail.price, order_detail.color, order_detail.size, customers.name, products.product_name, products.product_image FROM order_detail JOIN orders ON orders.serial=order_detail.orderid JOIN customers ON customers.serial=orders.customerid JOIN products ON products.productid=order_detail.productid WHERE customers.email='abc#yahoo.com') GROUP BY orders.date ORDER BY orders.date

Php, Mysql sort results based on number of records from another table

I'm joining two tables to display car brands. Here is the structure:
SELECT DISTINCT
b.title
FROM
brands as b
INNER JOIN items as i
ON i.brand_id = b.id
WHERE i.status = 1
ORDER BY COUNT(i.brand_id) DESC;
The above only produces one record. If I remove "ORDER BY COUNT(i.brand_id) DESC;" it displays all the records correctly.
I would like to sort result based on number of vehicles under each brand category. So for example if bmw category has the most car listed under, it should be the first one.
SELECT b.title
FROM brands as b
INNER JOIN items as i
ON i.brand_id = b.id
WHERE i.status = 1
GROUP BY b.title
ORDER BY COUNT(i.brand_id) DESC;
This should work for you.
I would use
SELECT b.title, count(i.brand_id)
FROM items i
LEFT JOIN brands as b
ON b.id = i.brand_id
WHERE i.status = 1
GROUP BY i.brand_id
ORDER BY COUNT(i.brand_id) DESC;
Your concern is the amount of cars in inventory. You want to break them down by how many of each brand you have. So, you're mainly concerned with the items tables and only need the brands table to get the information stored in the items table (brand name). Lastly, in order to get aggregate the number of brands of each, you must let MySQL know what you want in the GROUP BY.
I haven't used an EXPLAIN, but I would think the bottom query is more efficient.
You could join brands on an aggregate query:
SELECT b.title
FROM brands b
INNER JOIN (SELECT brand_id, COUNT(*) AS cnt
FROM items
WHERE status = 1
GROUP BY brand_id) i ON i.brand_id = b.id
ORDER BY cnt DESC;

I cant select data from database with inner join using mysql

I cant select data from database .
My table structrure is given below
customer table
id name
10 geetha
customer country table
id cust_id country
1 10 6
2 10 16
I got the result like these way
customer name country
geetha 6
geetha 16
But i want to get the one customer data only one time ie with out repeating.
customer name country
geetha 6
my query is
SELECT customer.name,customer.id,customer_country.country_id, customer_country.cust_id
FROM customer
INNER JOIN customer_country on customer.id = customer_country.cust_id
If you have duplicates in the customer_country table, then you need to choose one of them. Here is one method using max():
select c.name, max(cc.country_id)
from customer c inner join
customer_country cc
on c.id = cc.cust_id
group by c.name;
If you want all of them in a list, use group_concat():
select c.name, group_concat(cc.country_id) as countries
from customer c inner join
customer_country cc
on c.id = cc.cust_id
group by c.name;
For first record only, apply to the end: limit 1
SELECT customer.name,customer.id,customer_country.country_id,
customer_country.cust_id from customer
inner join customer_country on customer.id= customer_country.cust_id limit 1
try this i add distinct before customer_country.cust_id
SELECT customer.name,customer.id,customer_country.country_id, distinct customer_country.cust_id
FROM customer
INNER JOIN customer_country on customer.id = customer_country.cust_id

Categories