Incremental subtotal in MySQL result - mysql

I need to calculate - let's say - item prices based on purchase price and date (FIFO/LIFO). So, let's say I've made theese purchases:
3 x ABC for $100 at 2017-11-10
2 x ABC for $80 at 2017-11-12
5 x XYZ for $120 at 2017-11-11
7 x XYZ for $110 at 2017-11-12
Items first bought determine final product price, so ABC will cost $100 + markup for first 3 items sold, and $80 + markup for another 2.
What I need now is a sort of cache table, that should look like so:
SKU price max_qty
ABC 100 3
ABC 80 5
XYZ 120 5
XYZ 110 12
Please note that third column contains not purchased quantity, but rather a sort of "cap" of quantity to which this price is referring. That way I can quickly estimate sell price for 4 items of ABC by doing a simple JOIN on max_qty >= basket_qty. This is important as there will be much more reads than writes to this table.
What i'm struggling with is generating such table in a manner regarding performance and resource cost. I can't do it in a "query per sku" manner, as there can be quite a lot of records to update at a time. I've tried using MySQL variables;
SELECT
sku,
price,
#r := #r + qty AS max_qty
FROM
(SELECT #r := 0) AS r
JOIN
warehouse_items
GROUP BY
sku
ORDER BY
sku, date_in
This resultset would be easly inserted into cache table, but #r doesn't reset for each new sku in the result.

Related

how can I write a query in mySQL which shows the average trips in a day?

I have a list of IDs and the detail of the trips they've taken. I want to see how many trips each ID takes in a day on average but I don't know how to write this query. The data I have in my table is something like this:
ID
Ride_id
Date
1
123
2022-3-4
1
124
2022-3-4
1
111
2021-2-8
2
584
2019-4-18
2
256
2019-4-18
2
805
2020-5-8
2
127
2020-5-8
2
457
2020-5-8
3
100
2021-4-7
3
101
2021-4-7
3
202
2021-5-17
3
741
2021-5-17
So basically, the average rides ID=1 takes is 1.5 and the average rides ID=2 takes is 2.5 and so on. I need a query to calculate and show the result like this:
ID
Average_of_daily_trips
1
1.5
2
2.5
3
2
My current query uses only one condition: WHERE ID in ()
First count the trips on each day for each id, then make the average over those counts.
select id, avg(trips)
from (select id, count(*) as trips
from trips
-- where id in(1,2,3)
group by id, date) t
group by id
If you need to, you can uncomment the where clause in the subquery to filter for particular ids ...

Aggregating data percentage wise based on date related criteria from a table

I have legacy tables which tracks flight and had to extract data. We have three tables named booking, airlines and flighttype. Note this is a dummy samples
booking :
id
customer
request_date
airline
flightType
price
currency
1
1
11-20-2020 10:23
1
1
120
Eur
2
1
11-21-2020 10:24
1
2
110
CHF
3
2
11-01-2020 11:25
2
2
120
Eur
4
1
15-01-2020 10:23
1
1
100
Eur
5
1
11-01-2020 11:23
1
2
60
Eur
6
1
12-01-2020 10:23
1
3
35
Eur
airline :
id
airline
1
French
2
Swiss
type :
id
flightType
1
domestic
2
international
Now the data we are trying to figure out is number of bookings consecutively within x days (let say if two days it would mean how many bookings were made in 2 days) for various parameters like
airline
flightType
airline & flightype
currency
price total price
For example lets say I wish to see what is the percentage of customer who have made multiple bookings within x days across multiple airline I should be able to do so or if I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
I am trying to make self join to extract such data and then group it but I am always reaching a dead end
SELECT
t1.customer, t1.request_date, t1.airline, count(*)
FROM booking t1
JOIN booking t2
ON t1.customer= t2.customer
WHERE t2.request_date > t1.request_date and DATEDIFF(t2.request_date, t1.request_date) > 0 and DATEDIFF(t2.request_date, t1.request_date) <=2
GROUP BY t1.customer, t1.request_date
The problem I am facing is the date has time and it gives me wrong results. And I am not sure what is the right way to get %share of customers who make booking in such way like
% share of customers who book more than one flight / more than one type of flight within span of x days.
Sorry if the question is too vague or if this violates any rules.
By the way I am using mysql 5.5
I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
You can answer questions like this using window functions. For the first question, this looks like:
select count(distinct customer)
from (select b.*,
lag(request_date) over (partition by customer order by request_date) as prev_request_date
from booking b
) b
where request_date <= prev_request_date + interval <n> day;

mysql select filtered count for field along with total rows in table for same field

I have a table with customers and stores. Stores represents the places in which they have purchased something from me. I want to count how many times they have bought something from each store along with the total count of times they've purchased something from any store.
Sample Table called PURCHASE:
Customer Store
ABC Store 1
ABC Store 2
ABC Store 2
ABC Store 3
ABC Store 3
ABC Store 4
ABC Store 4
ABC Store 4
The results I want:
Customer Store Count Total
ABC Store 1 1 8
ABC Store 2 2 8
ABC Store 3 2 8
ABC Store 4 3 8
I tried something like this but it took a long time as there are over 40k records:
SELECT a.customer, store, count(a.customer) AS thisstore
FROM PURCHASE a
LEFT JOIN
(
SELECT COUNT(customer) AS totalsales,customer
FROM PURCHASE
GROUP BY customer) b
ON b.customer=N.customer GROUP BY a.customer;
If anyone knows of a better way to do this please let me know - thanks.
This query will give you the output you asked for and should be faster provided you have an index on PURCHASE.customer :
SELECT a.customer, a.store, count(*) AS thisstore
, (select count(*) from PURCHASE b where b.customer=a.customer) as total
FROM PURCHASE a
GROUP BY a.customer,a.store

SQL Pricing Tiers

I have a pricing lookup table in MySQL where I need to lookup the right pricing based on the transaction quantity.
Say for example, i have a pricing table pricing, looks like:
product quantity price
prod1 1 4
prod1 10 3
prod1 100 2
prod1 1000 1
prod2 1 0.4
...
And I have a table called transaction where contains the sales data:
product sales
prod1 144
prod2 2
...
How can I get the sales multiply by the right unit price based on the quantity.
Something likes:
product sales quantity unitPrice
prod1 144 100 2
prod2....
I tried to join two table on product but don't know where to go from there.
One way to get the price is using a correlated subquery:
select t.*,
(select p.price
from pricing p
where p.product = t.product and p.quantity >= t.quantity
order by p.quantity
limit 1
) as price
from transaction t;
A similar subquery can be used to get other information such as the pricing tier.
For performance, you want an index on pricing(product, quantity).

Select with a where clause and without it in the same query

I'm trying to find a way to sum amounts that match a specific term, and also amounts that don't match it. For example, if my table looks like this
user amount description
1 34 bike
1 78 toys
2 3 fuel
2 12 bike
I'm trying to get a table that will look like this in the end:
user amount spent on bike amount spent total
1 34 112
2 12 15
I'm using mysql
You can use a CASE statement within a SUM grouping:
SELECT user,
SUM(CASE WHEN description = 'bike' THEN amount ELSE 0 END) bike_amount,
SUM(amount) total_amount
FROM mytable
GROUP BY user