Get name, date and sum from orders in March - mysql

I have this query:
SELECT *
FROM ((orders_books
JOIN books ON orders_books.id_book = books.id)
JOIN orders ON orders_books.id_order=orders.id)
JOIN users ON user_id=users.id
WHERE date >='2019-03-1' AND date <= '2019-03-31';
Query result: https://image.prntscr.com/image/s3ngzzYrSd27mFib9HbLmA.png
I find number of orders:
SELECT name, date, SUM(book_price)
FROM ((orders_books
INNER JOIN books ON orders_books.id_book = books.id)
INNER JOIN orders ON orders_books.id_order=orders.id)
INNER JOIN users ON user_id=users.id
WHERE date >='2019-03-1' AND date <= '2019-03-31';
[Amount for all orders] : https://image.prntscr.com/image/o88Hf4uKSHGuZ2ESUECzuA.png
But I need to find the order amount separately for each order.

How about:
SELECT id_order, SUM(book_price)
FROM ((orders_books
INNER JOIN books ON orders_books.id_book = books.id)
INNER JOIN orders ON orders_books.id_order=orders.id)
INNER JOIN users ON user_id=users.id
WHERE date >='2019-03-1' AND date <= '2019-03-31'
GROUP BY id_order;

SELECT orders.id, SUM(book_price)
FROM ((orders_books
INNER JOIN books ON orders_books.id_book = books.id)
INNER JOIN orders ON orders_books.id_order=orders.id)
INNER JOIN users ON user_id=users.id
WHERE date >='2019-03-1' AND date <= '2019-03-31'
GROUP BY order_id;

If you need the sum for order.id then use group by orders.id
SELECT orders.id SUM(book_price)
FROM orders_books
INNER JOIN books ON orders_books.id_book = books.id
INNER JOIN orders ON orders_books.id_order=orders.id
WHERE date >='2019-03-1' AND date <= '2019-03-31'
group by orders.id

Related

SQL find highest date in all entries with a date older than x

I try to obtain a list of all customers my company has not had any assignments for in the last year.
SELECT MAX(assignment_date), full_name
FROM assignments
CROSS JOIN customers
WHERE assignments.customer_id = customers.id
AND assignment_date < '2017-01-01' -- Dynamic value from backend
GROUP BY full_name
ORDER BY assignment_date DESC
This does not seem to work as intended however, since it only returns some customers we did have assignments for in that timeframe. How would I go about implementing such a feature?
Try this code:
SELECT MAX(assignment_date), full_name
FROM customers
where id not in (SELECT id FROM customers inner join assigments on customers.id = assignments.customer_id WHERE assignment_date > '2017-01-01' )
This will return all customers in your database and remove all of them who did have assigments in last year. You should get all customers without assigments before '2017-01-01' as a result
left join customers to assignments where assignments.customer_id IS NULL
and assignment_date greater than '2017-01-01' i.e.
SELECT MAX(assignment_date), full_name
FROM assignments
WHERE assignments.customer_id IN
(SELECT customers.id
FROM customers
LEFT JOIN assignments ON assignments.customer_id = customers.id
WHERE assignments.customer_id IS NULL
AND assignment_date > '2017-01-01')
GROUP BY full_name
ORDER BY assignment_date DESC
I would suggest left join, group by and having:
SELECT MAX(assignment_date), full_name
FROM customers c LEFT JOIN
assignments a
ON a.customer_id = c.id
GROUP BY c.full_name
HAVING MAX(a.assignment_date) < '2017-01-01' OR
MAX(a.assignment_date) IS NULL
ORDER BY MAX(assignment_date) DESC;
It seems you want to show all customers with their last assignment date, but you want to restrict that list to customers that had no assignment since 2017-01-01. This means the dates you will be showing will be null for those customers who had never had an assignment and a date before 2017-01-01 for the others.
So outer join the last dates to the customers and only keep the rows where that date is before 2017-01-01 or null:
select c.full_name, a.max_date
from customers c
left join
(
select customer_id, max(assignment_date) as max_date
from assignments
group by customer_id
) a on a.customer_id = c.customer_id
where a.max_date < date '2017-01-01'
or a.max_date is null
order by a.max_date desc;

MySql Query Order BY datetime and Group By Id issue

Having issue with this query
there is 3 rows in comments table with different date-times, I want customer list with last comment created_date / updated_date.
but didn't getting last commented customer with group by customer
SELECT * FROM(
SELECT MAX(comments.`date_updated`), customer.id AS vid, comments.`date_updated` AS dts, comments.`id` AS comments_id, comments.* FROM customer
INNER JOIN comments ON comments.`customer_id` = customer.`id`
WHERE customer.`id` IN ('')
) AS v
GROUP BY v.`vid` LIMIT 0,50
You use a self join to comments table and filter row for each customer with latest date_updated
SELECT c.id AS vid, co.`date_updated` AS dts, co.`id` AS comments_id, co.*
FROM customer c
INNER JOIN comments co ON co.`customer_id` = c.`id`
LEFT JOIN comments co1 ON co.`customer_id` = co1.`customer_id` AND co.date_updated < co1.date_updated
WHERE co1.customer_id IS NULL AND c.`id` IN ('')
Or with inner join
SELECT c.id AS vid, co.`date_updated` AS dts, co.`id` AS comments_id, co.*
FROM customer c
INNER JOIN comments co ON co.`customer_id` = c.`id`
INNER JOIN (
SELECT customer_id, MAX(date_updated) date_updated
FROM comments
GROUP BY customer_id
) co1 ON co.customer_id = co1.customer_id AND co.date_updated = co1.date_updated
WHERE c.`id` IN ('')
You forgot order by clause
SELECT * FROM(
SELECT MAX(comments.`date_updated`), customer.id AS vid, comments.`date_updated` AS dts, comments.`id` AS comments_id, comments.* FROM customer
INNER JOIN comments ON comments.`customer_id` = customer.`id`
WHERE customer.`id` IN ('')
) AS v
GROUP BY v.`vid` LIMIT 0,50
ORDER BY created_date desc;

How do i sub query two joins?

I have created two queries that both return the required results independent of each other. I am trying to join them to have the returned values be customerName, Amount Ordered, and Amount Paid.
Currently, this query works but only returns the customerName. How can it get the query to return the other two columns?
SELECT c1.customerName
FROM
(SELECT cc.customerName, ROUND(SUM(od.priceEach * od.quantityOrdered), 2) as '$ Amount Ordered'
FROM customers cc
INNER JOIN orders o ON o.customerNumber = cc.customerNumber
INNER JOIN orderdetails od ON od.orderNumber = o.orderNumber
GROUP BY cc.customerName
) c1
INNER JOIN
(SELECT c.customerName, ROUND(SUM(p.amount), 2) as 'Total $ Amount Paid'
FROM customers c
INNER JOIN payments p ON p.customerNumber = c.customerNumber
GROUP BY c.customerName
) c2
WHERE c1.customerName = c2.customerName
GROUP BY c1.customerName
ORDER BY c1.customerName;
this should select the others column
SELECT c1.customerName, c1.Amount_Ordered as '$ Amount Ordered', c2.Total_Amount_Paid as 'Total $ Amount Paid'
FROM
(SELECT cc.customerName, ROUND(SUM(od.priceEach * od.quantityOrdered), 2) as Amount_Ordered
FROM customers cc
INNER JOIN orders o ON o.customerNumber = cc.customerNumber
INNER JOIN orderdetails od ON od.orderNumber = o.orderNumber
GROUP BY cc.customerName
) c1
INNER JOIN
(SELECT c.customerName, ROUND(SUM(p.amount), 2) as Total_Amount_Paid
FROM customers c
INNER JOIN payments p ON p.customerNumber = c.customerNumber
GROUP BY c.customerName
) c2
WHERE c1.customerName = c2.customerName
GROUP BY c1.customerName
ORDER BY c1.customerName;
simply add them to the select section:
SELECT c1.customerName, C1.amountOrdered, C2.amountPaid FROM ...
And one more word of advice - DONT use whitespace or special signs like $ in your column names, it is bad practice. I think it's a mistake that mySql even allows it

Exclude joined columns from a mysql query

I have the following query:
SELECT sa.*, d.day, TIME_FORMAT(timefrom.time, '%H:%i') AS time_from, TIME_FORMAT(timeto.time, '%H:%i') AS time_to
FROM staff s
INNER JOIN staff_availability sa
ON sa.staff_id = s.staff_id
INNER JOIN days d
ON d.day_id = sa.day_id
LEFT JOIN time_slots AS timefrom
ON timefrom.time_slot_id = sa.time_from
LEFT JOIN time_slots AS timeto
ON timeto.time_slot_id = sa.time_to
INNER JOIN users u
ON s.user_id = u.user_id
WHERE u.user_id = :user_id
I am using the alias time_from and time_to as the formatted times picked out of the time_slots table which are joined on with the staff_availability table.
The query is returning the following:
staff_availability_id staff_id day_id time_from(join) time_to(join) day time_from (alias) time_to (alias)
Is there any way I can exclude the join columns from the results?
you have to select them manually.
change this
SELECT sa.*
to
SELECT sa.staff_availability_id , sa.staff_id,....--what ever you want to select and dont select those you mentioned
select the columns as,
SELECT sa.staff_availability_id ,sa.staff_id,d.day, TIME_FORMAT(timefrom.time, '%H:%i') AS time_from, TIME_FORMAT(timeto.time, '%H:%i') AS time_to
FROM staff s
INNER JOIN staff_availability sa
ON sa.staff_id = s.staff_id
INNER JOIN days d
ON d.day_id = sa.day_id
LEFT JOIN time_slots AS timefrom
ON timefrom.time_slot_id = sa.time_from
LEFT JOIN time_slots AS timeto
ON timeto.time_slot_id = sa.time_to
INNER JOIN users u
ON s.user_id = u.user_id
WHERE u.user_id = :user_id

Multiple inner joins to get a complex report, not working

For the schema below, I need to get this report
This is what I have
select c.name, sr.name, count(o.order_id)
from contact c
INNER JOIN accounts a
ON c.account_id=a.account_id
INNER JOIN sales_reps sr
ON a.sales_rep_id =sr.sales_rep_id
INNER JOIN orders o
ON a.account_id =o.account_id
where o.order_id in (
select SUM(oi.quantity*p.price) from
order_items oi INNER JOIN parts p
on oi.part_id =p.part_id
)
group by a.account_id, c.name
But this does not give any results.
Please help.
Your where condition is not right, how should be a order_id equal a sum?
Try the below:
select
c.name, sr.name, COUNT(o.order_id), SUM(op.order_total)
FROM
contact c
INNER JOIN
accounts a ON c.account_id = a.account_id
INNER JOIN
sales_reps sr ON a.sales_rep_id = sr.sales_rep_id
INNER JOIN
orders o ON a.account_id = o.account_id
INNER JOIN
(SELECT
oi.order_id, SUM(oi.quantity * p.price) AS order_total
FROM
order_items oi
INNER JOIN
parts p ON oi.part_id = p.part_id
GROUP BY
oi.order_id
) op ON o.order_id = op.order_id
WHERE o.delivery_data >= CURDATE()
GROUP by c.contact_id
It won't give results as your WHERE ... IN SELECT is based on a query returning a sum() value which will not equal a key (most likely), or incorrect at best... and since you are dealing with a quantity and price which will have decimal precision (typically), you won't even get that to match even LESS likely...
I would swap the query around to pre-qualify the orders within a given date in question and sum that... THEN join to rest...
select
c.name,
sr.name,
PreQualified.NumberOrders,
PreQualified.OrderTotal
from
( select
o.Account_ID,
count( distinct o.order_id ) as NumberOrders,
sum( oi.quantity * p.price ) as OrderTotal
from
orders o
join order_items oi
on o.order_id = oi.order_id
join parts p
on oi.part_id = p.part_id
where
o.Delivery_Date >= CURDATE()
group by
o.Account_ID ) as PreQualified
JOIN Accounts a
on PreQualified.Account_ID = a.Account_ID
Join Contact C
on a.Account_ID = c.Account_ID
JOIN Sales_Reps sr
ON a.sales_rep_id = sr.sales_rep_id
If you want to count records use
count(*)
Instead of
count(o.order_id)