SQL query to get biggest price decreases - mysql

Need some help with a complicated SQL query.
We have the table pricechanges with the columns id, productid, date, price
For each productid, there are a number of rows with date = a timestamp and price = the price at the time of the timestamp.
Like this:
productid, date, price
3, 17/5-2016 22:00:00, 100
3, 18/5-2016 22:00:00, 120
3, 19/5-2016 22:00:00, 140
3, 20/5-2016 22:00:00, 120
3, 21/5-2016 22:00:00, 140
I would like to get the 10 products with the biggest price decrease in the last 7 days.
Is that possible somehow?
Thanks!
PS: It's a MySQL database.

IF i get the logic and then tables right the try the following:
select d.productID from
(
select a.productid, (a.price-b.price) as priceDiff
from products a
inner join products b
on a.productID=b.productID
and Date(a.date)=Date(b.date)+7
) d
order by priceDiff
Limit 10

Related

MYSQL Recursive query with conditions

I have 2 tables,
the first table contains id_product, its rate and its price.
ID_product
rate
Price
1
TSA1
0.12
2
TSA1
1.5
1
TSA2
0.14
2
TSA2
1.7
1
TSA3
NULL
2
TSA3
1.7
1
TASM4
1.68
I have an other table which contains a rate and its rate destination if the price for its rate is NULL. Its for always has a price for each product. Here for example, the product 1 doesnt have a price for the rate TSA3. The correspondance table says that if it doesnt have a price for this rate, use the price of TASM4.
Origin_rate
Destination_rate
TSA1
TAS2
TSA2
TAS3
TSA3
TASM4
So, How can I complete my first table? I think, i need a recursive query, but i dont know how to do it in SQL.
This query gets you the price hirarchically:
with recursive cte(id_product, rate, price, origin_rate) as
(
select id_product, rate, price, rate
from mytable
union all
select cte.id_product, cte.rate, t.price, t.rate
from cte
join map on map.origin_rate = cte.origin_rate
left join mytable t on t.id_product = cte.id_product
and t.rate = map.destination_rate
where cte.price is null
)
select id_product, rate, price
from cte
where price is not null
order by id_product, rate;

Find minimum value AND include correct column-values

I am trying to get the minimum price per travel and know which travel-details correspond to that minimum price per travel.
For this I have tried all kind of variations with subqueries, joins etc. but since there is not 1 primary key I cannot figure it out.
What I'm trying to achieve is get the travel with the lowest price, and then included in the record the details of the travel with that lowest price.
SELECT travel_id, persons, days, MIN(`price`) AS `price`
FROM travel_details
WHERE 1
GROUP BY `travel_id`
HAVING MIN(price);
Simple version of my table-columns, columns are:
travel_id, persons, days, price
Those columns together form the primary key.
A travel can be booked for various persons, days and prices. It can also occur that there are multiple price-options for the same combination of travel_id, persons, and days.
E.g.,
100, 2, 4, **250**
100, 2, 4, **450**
100, 2, **5**, 450
101, 2, 4, 190
101, 2, 5, 185
Being travel_id 100 for 2 persons for 4 persons.
What I would like to achieve is return:
100, 250, and then with correct corresponding values:
100, 2, 4, 250
101, 2, 5, 185
Now my result just mixes all the other data. When I include those columns in the group by, it will not only group on travel_id anymore, but also e.g., on persons. Then it will return all combinations for a travel_id and persons.
Any idea how to approach this?
Select a.travel_id, a.persons, a.days, a.price from travel_details a
JOIN (Select travel_id,MIN(Price) as p from travel_details group by travel_id) b
on b.travel_id=a.travel_id and b.p=a.price
The above query uses self join. Derived table b will contain travel_id along with min price.
SELECT travel_id, persons, days, price
FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY travel_id, persons, days ORDER BY price) AS RowNum,
travel_id, persons, days, price
FROM travel_details
) X
WHERE X.RowNum = 1
Hello #PeterH, would this work for you?
You can use IN() to do this:
SELECT * FROM travel_details t
WHERE (t.travel_id,t.price) IN(SELECT s.travel_id,min(s.price)
FROM travel_details s
GROUP BY s.travel_id)
GROUP BY t.travel_id; // this last group-by is to filter doubles when there are multiple records per travel with the lowest price.

MS SQLServer How to multiply two columns, then add them all together..?

I'm new here. First post. I'd really appreciate some help.
I'm trying to calculate total sales for all products sold.
I have a Quantity column and a Price column.
I understand how to multiply these two columns, BUT I do not know how to add them all together in the same query.
Here is an example:
Quantity: 2, 3, 1 Price: 2, 4, 5
I could do Quantity * Price to get: 4, 12, 5
But then how would I add 4 + 12 + 5 to get the total? I need this step to be included in the same query.
EDIT: Both the Quantity and Price columns are in the same table.
SALES (Quantity, Price)
I am using Microsoft SQL-Server.
Example if you have one table:
SELECT dbo.orderid,
SUM(dbo.quantity * dbo.price) AS grand_total,
FROM ORDERITEM
If you have two tables instead of one, then:
SELECT oi.orderid,
SUM(oi.quantity * p.price) AS grand_total,
FROM ORDERITEM oi
JOIN PRODUCT p ON p.id = oi.productid
WHERE oi.orderid = #OrderId
GROUP BY oi.orderid
Adding all the rows (orderid numbers) up together to get a total, you would simply groupby and them select the sum value. Example below:
SELECT Orderid, SUM(quanity) AS Expr1, SUM(price) AS Expr2, SUM(quanity * price) AS Total
FROM dbo.mytable
GROUP BY pid
HAVING (pid = 2)
Or this in a SQL view showing the total QTY and Price:
SELECT Orderid, SUM(quanity) AS Quanity, SUM(price) AS Price, SUM(quanity * price) AS Total
FROM dbo.mytable
GROUP BY pid

In a product database, How to calculate pricechange from two periods, and group by category

hi have a product database which the price is changing every month (period) - I want to show the price-change in percent, grouped by category. The schema is something like this: id, name, category, price, period. (The period is YYYY-MM)
A rows could be:
123, "Chair" , "Furniture", 123 , 2013-05 -- for may
123, "Chair" , "Furniture", 110 , 2013-06 -- for june
Is it possible in a SQL-query to calculate the percentage difference for each product for each month? And at the same time group categories together?
The challenge in this sort of query is finding the previous period. Here is one approach:
select p.*,
(p.price -
(select p2.price
from product p2
where p2.id = p.id and p2.period < p.period
order by period desc
limit 1
) - 1
) * 100 as PercentageChange
from product p
order by category;
It uses a correlated subquery and it makes the assumption that there is a price by every month. By "group categories together", I assume you mean to sort by the category. (Aggregating by the category would lose the information about each product.)
Note that the above syntax could vary by database. Different databases have different way of limiting the results to one row.

mysql insert if condition true

First, here's the concise summary of the question:
Is it possible to run an INSERT statement conditionally? Something akin to this:
IF(expression) INSERT...
Now, I know I can do this with a stored procedure.
Now, I want to do that
Let's assume we have the following 3 tables:
products: id, qty_on_hand
orders: id, product_id, qty
roomTable :id,product_id,room_number,booked_status
Now, let's say an order for 20 rooms (product id 2) comes in. We first check total qty of given product_id from orders table as total_qty and total_qty < qty_on_hand if it return true then insert order values and update 1 room after last booked_status='Y' room from roomTable with booked_status ='Y' and give the id of that room .
Problem is that I am not able to make the join query . what i done so far -
INSERT INTO orders(product_id, qty)
SELECT 2, 20 FROM products WHERE id = 2 AND qty_on_hand >= 20
For those of you who need more detail around how this technique works from Mt. Schneiders,
INSERT INTO orders(product_id, qty)
SELECT 2, 20
FROM products
WHERE id = 2 AND qty_on_hand >= 20 + (select sum(qty) from orders where product_id = 2)
What is going on here is that the result of the select statement is hard coded. In this case we are taking INSERT INTO orders(product_id, qty) VALUES(2, 20) and replacing VALUES(2,20) with SELECT 2, 20. The result of the SELECT is hard coded but only returns a value if the condition is met.
I found this article that explains this technique more in depth:
http://boulderapps.co/dont-insert-when-maximum-is-reached
Wouldn't it be something like this?
INSERT INTO orders(product_id, qty)
SELECT 2, 20
FROM products
WHERE id = 2 AND qty_on_hand >= 20 + (select sum(qty) from orders where product_id = 2)
So, it would not insert if the last orders quantity plus quantity from the order being inserted is less or equal whats in hand.