Getting only the last customer purchase - sql

I have to write a query to get the following result: "We want to give a coupon with a 10% value of the last customer purchase. The customers eligible for this coupon must have made another purchase before the last one that is equal or bigger than the last one. Create a query that returns the coupon values for each one of the eligible customers."
I have the following query already written, who returns to me all the purchases and then the coupons' values, but for the result to be right I need only the rows matching the last customer purchase to be shown. Any idea on how to do this?
SELECT * FROM(
select *,
lag(PaymentValue) over (PARTITION BY IDCustomer ORDER BY ApprovalDate) LastPurchaseValue,
PaymentValue*0.1 as CouponValue
from (
SELECT Customers.customer_unique_id as IDCustomer,
Orders.order_id as IDOrder,
order_approved_at as ApprovalDate,
SUM(Payments.payment_value) as PaymentValue
from olist_customers_dataset as Customers
inner join olist_orders_dataset as Orders on Customers.customer_id = Orders.customer_id
INNER JOIN olist_order_payments_dataset as Payments on Payments.order_id = Orders.order_id
GROUP BY IDCustomer, IDOrder, ApprovalDate
ORDER BY IDCustomer
)
) WHERE LastPurchaseValue > PaymentValue
Here you can find the schema:

Related

get the name of product with the maximum number of orders

I have 2 tables orders and product as
orders has only one field (order_id)
and the products have a reference to the order_id,
how to get the name of product with the maximum number of orders
I tried this query
SELECT MAX(mycount)
FROM
(Select products.product_name , count(orders.order_id) mycount
FROM Orders, products
WHERE products.order_id = Orders.order_id
GROUP BY orders.order_id)
but it only gave me the max value,
how to add the name field (products.product_name) to the result??

Finding the most frequently occurring combination

I have two table with name Orders and Products,The order table contains the number of specific orders made by a customer and the products included in that order is in the Products table.
My requirement is to get the number of total orders against the most frequently coming products.
means for these products product 1,Product 2, product 3 what is the total orders,If an order contains 10 Products which contains Product 1 ,Product 2 and Product 3 that order should be counted.
For an order_id there can be multiple products will be there and i'm confused on how to get this result.Can anyone share or suggest a solution on how to get this?
I'm using PostgreSQL.
Below is the sample query ,
SELECT
"Orders"."order_id",pr.product_name
FROM
"data"."orders" AS "Orders"
LEFT JOIN data.items i On i."order_id"="Orders"."order_id"
LEFT join data.products pr on pr."product_id"=i."product_id"
WHERE TO_CHAR("Orders"."created_at_order",'YYYY-MM-DD') BETWEEN '2019-02-01' AND '2019-04-30'
ORDER BY "Orders"."order_id"
Desired Result will be like this(3 columns),The most purchased product combination with number of occurring orders.
Product 1, Product 2,Product 3,etc..... , Number Of Orders
This is the sample data output,Need the product list which is purchased in combination the most.(As of now i have given only 3 columns for sample but it may vary according to the number of PRODUCTS in an order).
and example
SELECT
"Orders"."order_id",
string_agg(DISTINCT pr.product_name,::character varying, ',') AS product_name
count(1) AS product_no
FROM
"data"."orders" AS "Orders"
LEFT JOIN data.items i On i."order_id"="Orders"."order_id"
LEFT join data.products pr on pr."product_id"=i."product_id"
WHERE TO_CHAR("Orders"."created_at_order",'YYYY-MM-DD') BETWEEN '2019-02-01' AND '2019-04-30'
GROUP BY "Orders"."order_id"
ORDER BY count(1);
You can try to use group by clause.
If you want to generally get the number of orders against some products then you can just count the number of orders grouped on the products from product table. Query should look something like this:
SELECT product_id, COUNT(*)
FROM data.products
GROUP BY product_id
ORDER BY COUNT(*)
LIMIT 1;
Hope this helps!
Try to use GROUP BY and take MOST counted value as below-
SELECT
pr.product_name,
COUNT(DISTINCT Orders.order_id)
FROM
"data"."orders" AS "Orders"
LEFT JOIN data.items i On i."order_id"="Orders"."order_id"
LEFT join data.products pr on pr."product_id"=i."product_id"
WHERE TO_CHAR("Orders"."created_at_order",'YYYY-MM-DD') BETWEEN '2019-02-01' AND '2019-04-30'
GROUP BY pr.product_name
ORDER BY COUNT(DISTINCT Orders.order_id) DESC
LIMIT 1 -- You can use the LIMIT or NOT as per requirement

SQL, What is the total amount each client has paid us?

I've got a little problem here: I've created 5 tables: Customer, Invoice, Line, Product and Vendor.
Task asks me:
What is the total amount each client has paid us?
And the following comment:
To find the total amount each client has paid us you need to join
customer table with invoice and line. Group by customer code, sum
price from line. Balance would only show whether client owes us money.
Also when you perform a SUM there should also be a group by statement.
I've made a code, but stuck, because got confused:
SELECT Invoice.CUS_CODE
FROM Invoice
INNER JOIN Customer ON Invoice.CUS_CODE = Customer.CUS_CODE
WHERE Invoice.INV_NUMBER IN (
SELECT SUM(Line.LINE_PRICE)
FROM Line
INNER JOIN Invoice ON Invoice.INV_NUMBER = Line.INV_NUMBER
GROUP BY LINE_PRICE)
GROUP BY Invoice.CUS_CODE;
So, I need to group INV_NUMBER from Invoice table by CUS_CODE (customer code) from Customer and sum the LINE_PRICE of grouped INV_NUMBER. In the end group by CUS_CODE.
Thank You in advance.
UPD: Tables
Customer table
Line table
Invoice table
It seems that you are up to simple LEFT JOIN with GROUP BY
SELECT CUS_CODE, CUS_LNAME, CUS_FNAME, SUM(Line.LINE_PRICE)
FROM Customer
LEFT JOIN Invoice ON Invoice.CUS_CODE = Customer.CUS_CODE
LEFT JOIN Line ON Invoice.INV_NUMBER = Line.INV_NUMBER
GROUP BY CUS_CODE, CUS_LNAME, CUS_FNAME

Subquery amount not coming in full

I have this query:
Select I.Invoice_Number, PA.Invoice_Number, I.Line_Amount, PA.Invoiced_Amount
from XXX as PA
Left join (select Invoice_Number, Line_Amount from Invoices) as I
on PA.Invoice_Number = I.Invoice_Number
Group by PA.Invoice_Number;
Both should give me the same amount of cost (I.Line_Amount = PA.Invoice_Amount) per Invoice_Number, yet I.Line_Amount is only bringing the first row on the list, while PA.Invoiced.Number brings the sum of the cost on that Invoice.
I tried using sum(Line_Amount) within the subquery but all records come out as Null.
Is there a way for me to join both tables and make sure that the amounts per invoice match to the total amount of that invoice?
Thanks!!
If I understand you correctly (and you want to make sure that sum of Line_Amount in Invoices table is the same as Invoiced_Amount in XXX table) the second table should have invoice number and sum of amounts:
select I.Invoice_Number, PA.Invoice_Number, I.total, PA.Invoiced_Amount
from XXX as PA
left join (
select Invoice_Number, sum(Line_Amount) as total
from Invoices
group by Invoice_Number
) as I
on PA.Invoice_Number = I.Invoice_Number
You can try it here: http://sqlfiddle.com/#!9/d1d010/1/0

distinct record by with oldest date

Ok i have 2 tables
they have matching customer id fields
customer has cust_id as a primary field and orders has many cust_Ids
I want to display the first order record (earlist dated) for each customer id
Select customer.*, orders.*
from customer , orders
where orders.date = (select max(orders.date) from orders
where customer.customer-id = orders.customer-id)
This query combines the tables but i have multiple entries for each customer id and I only want the oldest date entry for each customer-id
How do I just get the oldest date record for each customer
You could accomplish this using an outer apply. That would look something like this:
select c.*, o.*
from customer c
outer apply (
select top 1 *
from orders o
where o.Customer-ID = c.Customer-ID
order by o.Date asc
) o