the following query no.1 and query no.2 are working each line..
1.
SELECT app_user.au_userid, SUM(order_detail.od_quantity), (order_detail.od_quantity*SUM(order_detail.od_subtotal)) AS total_amount FROM app_user JOIN orders ON app_user.au_id = orders.o_au_id JOIN order_detail ON orders.o_id = order_detail.od_order_id GROUP BY app_user.au_userid
2.
SELECT COUNT (app_user.au_id) FROM app_user JOIN orders ON app_user.au_id = orders.o_au_id GROUP BY app_user.au_id
the following query no.3 doesn't working..
3.
SELECT app_user.au_userid, (SELECT COUNT (app_user.au_id) FROM app_user JOIN orders ON app_user.au_id = orders.o_au_id GROUP BY app_user.au_id) AS total, SUM (order_detail.od_quantity), (order_detail.od_quantity*SUM (order_detail.od_subtotal)) AS total_amount FROM app_user JOIN orders ON app_user.au_id = orders.o_au_id JOIN order_detail ON orders.o_id = order_detail.od_order_id GROUP BY app_user.au_userid
The simplest method uses COUNT(distinct):
SELECT o.o_au_id, COUNT (DISTINCT o.o_id) AS num_orders,
SUM(od.od_quantity),
SUM(od.od_quantity * od.od_subtotal) AS total_amount
FROM orders o JOIN
order_detail od
ON o.o_id = od.od_order_id
GROUP BY o.o_au_id;
Notes:
You don't need app_users, because you have the user id in the orders table.
Table aliases make the query easier to write and to read.
For calculating the total amount, you should be doing the multiplication before the summation.
To get the number of orders, use count(distinct).
Related
I have two tables that track sales:
orders order_line_items
------ ----------------
id id
customer_id order_id
created_datetime item_id
quantity
was_paid_for
An order can have many order_line_items. For some orders, all of the line items have been paid for. For other orders, they have not all been paid for.
I am trying to fetch a list of all the orders for a specific customer, and indicate if the order was fully paid for, or not. I have it working with this query:
SELECT o.id,
(SELECT count(*) from order_line_items WHERE order_id = o.id AND was_paid_for = 0) = 0 as isFullyPaid
FROM orders o
WHERE o.customer_id = 12345
However some customers have 1000+ orders and the query takes 70 seconds to run (this is a simplified example, the real one joins in five other tables).
Is indexes the only way to speed this up? Thanks.
You could try adding the following index to the order_line_items:
CREATE INDEX idx ON order_line_items(order_id, was_paid_for);
That being said, you also could try using the following join version of your query:
SELECT o.id, COALESCE(oli.cnt, 0) = 0 AS isFullyPaid
FROM orders o
LEFT JOIN
(
SELECT order_id, COUNT(*) AS cnt
FROM order_line_items
WHERE was_paid_for = 0
GROUP BY order_id
) oli
ON oli.order_id = o.id
WHERE o.customer_id = 12345;
The same index suggestion applied to the above join query.
I have 5 tables connected with each other in the image
[![Image1][1]][1]
I have tried writing query
SELECT lastname,firstname
FROM customer,purchase_order
where customer.customer_id=purchase_order.customer_id
What parameter should I consider for most purchase?
You can solve that by adjusting the select clause (remove order_id).
Then you will need a HAVING clause to implement the condition to only show the customers with the most purchase orders.
SELECT lastname,firstname
FROM customer
INNER JOIN purchase_order
ON customer.customer_id=purchase_order.customer_id
GROUP BY customer_id
ORDER BY COUNT(order_id) DESC LIMIT 1;
select lastname, firstname from customer c
inner join (
select customer_id, count(1) from purchase_order
group by 1
order by 2 desc limit 1) most
/* the above sub-query named as 'most' fetched the customer id with the maximum
number of orders */
on c.customer_id = most.customer_id; -- this is a simple join of customers table with the table generated from sub-query above
SELECT c.firstname,c.lastname
FROM customer c
JOIN purchase_order po
ON c.customer_id = po.customer_id
GROUP BY c.firstname,c.lastname
ORDER BY COUNT(po.order_id) DESC LIMIT 1;
I have the following (here simplified) database and want to get the month with the highest revenue.
invoices
- id
- order_id
- issued (timestamp)
orders
- id
orderItems
- id
- order_id
- article_id
articles
- id
- price
So far I got the following statement:
Select articles.price * orderItems.order_id as revenue, Extract(month
from invoices.issued)
FROM orderItems
INNER JOIN articles ON orderItems.article_id = articles.id
Inner JOIN orders ON orderItems.order_id = orders.id
Inner JOIN invoices ON orders.id = invoices.order_id
GROUP BY year(issued), month(issued)
Order by revenue DESC Limit 1
The calculated revenue is wrong as the price is multiplied with the order_id but should be actually multiplied with the count of the respective order_id. I tried to implement count(orderItems.order_id) but it's not working. Any ideas? Thanks!
I think you want:
SELECT year(i.issued), month(i.issued), SUM(a.price) as revenue,
FROM orderItems oi JOIN
articles a
ON oi.article_id = a.id JOIN
orders o
ON oi.order_id = o.id JOIN
invoices i
ON o.id = i.order_id
GROUP BY year(i.issued), month(i.issued)
ORDER BY revenue DESC
LIMIT 1;
In other words, this is a simple aggregation query. There is no need -- ever -- to multiply by orderid. Also note that this query introduces table aliases so the query is easier to write and to read.
I'm trying to create a view of some columns from 3 different tables. One of the columns 'OrderNumber' is in 2 of the tables so I'm trying to do a UNION for them, but because I've made a subquery it returns an 1242 error and won't return more than 1 row. I just want to know how I can rewrite this query so that there are no subqueries, or is there someway to bypass it. Or perhaps I need to write multiple queries? Though I'd prefer to keep it to the one query, thanks.
CREATE VIEW CustOrderItems AS
SELECT CustFirstName,
CustLastName,
(SELECT OrderNumber
FROM Orders
UNION
SELECT OrderNumber
FROM Order_Details)
OrderDate,
ShipDate,
QuantityOrdered * QuotedPrice as ItemTotal
FROM Customers JOIN Orders JOIN Order_Details;
Substitute whatever your customer id
drop view if exists custorders;
create view custorders as
SELECT c.CustFirstName,
c.CustLastName,
o.OrderNumber order_ordernumber,
od.OrderNumber orderdetails_ordernumber,
o.OrderDate,
o.ShipDate,
od.QuantityOrdered * od.QuotedPrice as ItemTotal
FROM Customers c
JOIN Orders o on c.id = o.cust_id
JOIN Order_Details od on o.ordernumber = od.ordernumber
where c.id = ?
It's not clear what are your join criteria because the statement syntax is bad. But I assume you want to join on OrderNumber like SELECT ... FROM Customers INNER JOIN Orders ON Customers.OrderNumber = Orders.OrderNumber. In this case, if you want to use order numbers from two tables just repeat the query and make union of the two like:
SELECT ,,, FROM Customers INNER JOIN Order_Details ON Customers.OrderNumber = Order_Details.OrderNumber
UNION
SELECT FROM Customers INNER JOIN Orders ON Customers.OrderNumber = Orders.OrderNumber
I have one table Customers with CustomerID and PhoneNumber, the second table is Orders that has CustomerId and OrderNumber and a third table OrderDetails that has OrderNumber, PriceOfOneUnit and UnitsOrdered. I need to find the PhoneNumber for the customer who placed the largest order (PriceOfOneUnit * UnitsOrdered). Doing a count(PriceOfOneUnit*UnitsOrdered) as A1 and then `Group By CustomerId Order By A1 DESC LIMIT 1 is evidently not working after joining the 3 tables. Can anyone help.
If we take you at your word, and what you want is the biggest single line-item rather than the largest order, you can find the largest line-item and then find the order to which it belongs and then the customer who placed that order. You can use a dummy aggregate function to pull back the order id from orderDetails.
EDIT:
OK, for someone just starting out, I think it can be clearer to think in terms of Venn diagrams and use what are called Inline Views and subqueries:
select customername, phone
from customer
inner join
(
select o.id, customerid from orders o
inner join
(
select od.orderid from orderdetail od
where (od.qty * od.itemprice) =
(
select max(od.qty * od.itemprice)
from orderdetail as od
)
) as biggestorder
on o.id = biggestorder.orderid
) as X
on customer.id = X.customerid
Each of the queries inside parentheses returns a set that can be joined/intersected with other sets.
Give this a try,
SELECT cus.CustomerId, cus.PhoneNumber
FROM Customers cus
INNER JOIN Orders a
ON cus.CustomerId = a.CustomerId
INNER JOIN OrderDetails b
On a.OrderNumber = b.OrderNumber
GROUP BY cus.CustomerId, cus.PhoneNumber
HAVING SUM(b.PriceOfOneUnit * b.UnitsOrdered) =
(
SELECT SUM(b.PriceOfOneUnit * b.UnitsOrdered) totalOrdersAmount
FROM Orders aa
INNER JOIN OrderDetails bb
On aa.OrderNumber = bb.OrderNumber
GROUP BY aa.CustomerId
ORDER BY totalOrdersAmount DESC
LIMIT 1
)