Pulling last 10 orders from mysql table - mysql

I'm new to mysql and I'm trying to figure out if there is a way that you can pull information from the the last 5 most recent orders.
I'm trying to pull orderNumber, productName, and firstname for last 5 most recent orders.
I created 2 dummy tables that I'm working with:
Table:
orders
Fields:
orderNumber
customerOid
orderInformationOid
purchaseDateTime
Table:
customerData
Fields:
customerOid
firstName
middleInitial
lastName
Table:
products
Fields:
productOid
productName
companyOid
I was thinking an INNER JOIN but how to determine the most recent orders?

I suppose there's a productOid column in your orders table, then you can use this query:
SELECT o.orderNumber, p.productName, c.firstname
FROM
(SELECT orderNumber, customerOid, productOid
FROM orders
ORDER BY purchaseDateTime DESC
LIMIT 5) o
INNER JOIN customers c ON o.customerOid = c.customerOid
INNER JOIN products p ON o.productOid = p.productOid

Related

Joining the tables while manipulating SELECT

I am new to SQL and am wondering how to join two tables based on the user ID while, at the same time, manipulating one of the columns. I have the table of orders per ID, and another table with ID demographics. I want to sum the orders per ID, and then join the demographics information.
Separately, the codes work:
This one sums the orders per id up:
SELECT SUM(order) AS expenses, id
FROM orders
GROUP BY id;
And this one joins another table:
SELECT orders.id, demographics.*
FROM orders
JOIN demographics
ON orders.id = demographics.user;
But how can you do the two simultaneously? So the table becomes like:
id | expenses | demographics.1 | demographics.2 | demographics.3 | etc
SELECT orders.id, sum(order) as expenses, max(demographics.1), max(demographics.2),...
FROM orders
JOIN demographics
ON orders.id = demographics.user
Group by orders.id
select
o.id,
d.demographics.1,
d.demographics.2,
d.demographics.3,
sum (o.order) Expenses
from order o,
demographics d
where 1=1
and.o.id = d.user
group by
o.id

mySQL SQL joined table then find rows with duplicates

I have two tables:
Orders
orders_ID
orderDate
Order Details
product_ID
order_ID
quantity
Products
product_ID
productName
productDescription
I want to find all the records in the Order Details of product_ID 1 and 4 (so trying to see when one order contains both of these products). So ran this code - the INNER JOIN creates a results table that contains only orders that contain product 1, 4, or 1 and 4.
Then I want to count all of the "Order Details".order_ID duplicates - these would be all of the orders that contain 1 and 4 (note- trivial database - a given order doesn't contain more than 1 of any product).
Here is my code - doesn't quite work - any thoughts?
SELECT order_ID, COUNT(*) TotalCount
FROM
(SELECT * FROM Orders o INNER JOIN "Order Details" od ON o.order_ID = od.order_ID
WHERE od.product_ID = 1 OR od.product_ID = 4)
GROUP BY order_ID
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
Thanks- I looked through the forum but didn't see anything that helped me - been trying for some time.
I think what you want is a JOIN:
select prod1.order_id from `Order Details` prod1 JOIN `Order Details` prod4 on prod1.order_ID=prod2.order_ID where prod1.product_ID=1 and prod2.product_ID=4;

Select max value from different tables in mysql

I want to select the most expensive product each customer bought, but I have the information in 3 tables: Customers, Purchases, ProductsPrices.
Tables look like:
Customers:
Customer_ID | Customer_Name
Purchases:
Customer_ID | Product_ID
ProductPrices:
Product_ID | Price
What i'm running is:
SELECT
Customer_Name, max(Price), Purchases.Product_ID
FROM Customers
LEFT JOIN Purchases
ON Customers.Customer_ID=Purchases.Customer_ID
LEFT JOIN ProductPrices
ON Purchases.Product_ID=ProductPrices.Product_ID
GROUP BY Customer_Name
ORDER BY ABS(Price) DESC
;
And the output i'm getting is the names and the highest purchase correct, but the product_id is the first, and not associated with the highest price.
Can you help me to spot what am I doing wrong?
EDIT:
To make it easier for you, I created this:
http://sqlfiddle.com/#!2/db7f9/1
Try this:
select distinct c.Customer_Name,pp.Product_Id,m.Price
from
(select Customer_ID,max(Price) as Price
from Purchases p join ProductPrices pp on (p.Product_ID=pp.Product_ID)
group by Customer_ID) m
join Customers c on (m.Customer_ID=c.Customer_ID)
join ProductPrices pp on (pp.Price=m.Price)
join Purchases p on (m.Customer_ID=p.Customer_ID and p.Product_ID=pp.Product_ID)
Note: If a customer purchased multiple products with the same price, this will give you muliple rows per Customer.
try this
SELECT Customer_Name, max(Price) price , Product_ID FROM (
SELECT
Customer_Name, Price, Purchases.Product_ID
FROM Customers
INNER JOIN Purchases
ON Customers.Customer_ID=Purchases.Customer_ID
INNER JOIN ProductPrices
ON Purchases.Product_ID=ProductPrices.Product_ID
ORDER BY ABS(Price) DESC
)t
GROUP BY Customer_Name
DEMO HERE
OUTPUT:
CUSTOMER_NAME PRICE PRODUCT_ID
John 30000 3
Kate 30000 3
Peter 20000 2

mySQL using same table/fields multiple times in a single query

I have 2 tables in mySQL database :
customers
============
customer_id (1, 2 )
customer_name (john, mark)
orders
============
order_id = 123
customer_id = 1
customer_from_id = 2
Idea is to do single query on orders table joining customers table whereby
orders.customer_id = customers.customer_id
orders.customer_from_id = customers.customer_id
to get the "customer_name" by JOIN(ing) two tables.
So how do i do single query on "orders" and expand all (2) "customer_name" fields so result looks like this :
+--------+------------+---------------------+------------------+---------------------+
order_id customer_id customer_order_name customer_from_id customer_from_name
+--------+------------+---------------------+------------------+---------------------+
123 1 john 2 mark
+--------+------------+---------------------+------------------+---------------------+
It means using same table 2x in a query and
aliasing output field "customer_name" 2x with
"customer_order_name" and "customer_from_name".
It shall be simple but i am stuck.
Any help would be much appreciated.
Thank You.
Join twice and use prefix and give aliases:
select order_id, buyer.customer_id, buyer.customer_name, seller.customer_id as customer_from_id, seller.customer_name as customer_from_name from orders o
join customers seller on o.customer_from_id = seller.customer_id
join customers buyer on o.customer_id = buyer.customer_id;
select order_id, c1.customer_id as customer_id,
c1.customer_name as customer_order_name ,
c2.customer_id as customer_from_id,
c2.customer_name as customer_from_name
from orders o
left join customers c1 using (customer_id)
left join customers c2 on o.customer_from_id = c2.customer_id;
fiddle

WHERE value IS NOT IN (subquery)

I've been struggling with this query.
I have two tables. One with coupons and Invoicenumbers. One with Invoicenumbers and customer names.
I need to get the customers who have not used a given coupon.
Here are the tables:
Promotion table:
Promotions
Invoice | Coupon
----------------
1 | couponA
2 | couponB
3 | couponB
Orders Table:
Orders
Invoice | Customer
------------------
1 | Jack
2 | Jack
3 | Jill
So Jack has used coupons A and B. And Jill has only used coupon B.
If my query were select customers who have not used coupon A, I should get Jill.
This works, but it seems clumsy and slow. Is there a better way?
SELECT Customer
FROM Promotions INNER JOIN Orders
ON Promotions.Invoice = Orders.Invoice
WHERE Customer NOT IN(
SELECT Customer
FROM Promotions INNER JOIN Orders
ON Promotions.Invoice = Orders.Invoice
WHERE Coupon = couponA)
GROUP BY Customer
Thanks for looking!
edit:
Here's an SQLFiddle schema
http://sqlfiddle.com/#!2/21d31/6
Updated: We should use prefer to use joins for better performance when its easy to do for us. Join vs. sub-query
Sql Fiddle
Select distinct Customer from orders o
join
(
SELECT distinct Customer as changedname FROM Orders o2
join
(
Select distinct invoice from Promotions where Coupon='couponA'
) t3
on o2.invoice = t3.invoice
) t2
on o.customer != t2.changedname;
Note: I changed column name customer for t3 because two joined tables must have different column names
Explanation:
Using inner or sub query is expensive when you have big data. use joins instead, lets learn converting subquery to join
With Subquery We had:
Select distinct Customer from orders where customer not in
(SELECT distinct Customer FROM Orders where invoice in
(Select distinct invoice from Promotions where Coupon='couponA'));
Converting sub-query to join
First step:
Select distinct Customer from orders o
join
(
SELECT distinct Customer as changedname FROM Orders where invoice in
(Select distinct invoice from Promotions where Coupon='couponA')
) t2
on o.customer != t2.changedname;
2nd step:
Select distinct Customer from orders o
join
(
SELECT distinct Customer as changedname FROM Orders o2 where invoice
join
(
Select distinct invoice from Promotions where Coupon='couponA'
) t3
on o2.invoice = t3.invoice
) t2
on o.customer != t2.changedname;
And that's it, much faster for tables having numerous rows
Original answer:
Use not in. Have a look.
Select distinct Customer from orders where customer not in
(SELECT distinct Customer FROM Orders where invoice in
(Select distinct invoice from Promotions where Coupon='couponA'));
Edit I have added distinct to make query faster
SQL Fiddle
SELECT DISTINCT o2.customer FROM ORDER o2
LEFT JOIN (promotions p1
JOIN Orders o1 ON p1.cuopon = 'CuoponA' AND p1.invoice = o1.invoice ) p3
ON o2.customer = p3.customer
WHERE p3.customer IS NULL
Try this query instead:
SELECT DISTINCT Customer
FROM Orders o1
WHERE NOT EXISTS (
SELECT 1
FROM Orders o2
INNER JOIN Promotions ON Promotions.Invoice = o2.Invoice
WHERE o1.Customer = o2.Customer AND Coupon = 'couponB')
The idea is to get rid of the GROUP BY by removing a join in the top part of the query, and also eliminate the NOT IN by making a coordinated subquery.
Here is a link to sqlfiddle.
Try this with a right join
SELECT Customer, Coupon
FROM Promotions
RIGHT JOIN Orders ON Promotions.Invoice = Orders.Invoice
AND Coupon = 'couponA'
GROUP BY Customer
HAVING Coupon IS NULL