mysql query dynamic date range - mysql

I've created a website showing the prices of the fruits and vegetables of my province. These prices are updated every day (aprox. +250 rows each day).
For that reason I created a MySql table to speed up the access to this information.
On the table showed on my Web site I want to limit the date showed up to 1 week and not all the dates available on the database. Taking in consideration that the database is increased daily I need a query for this dynamic date request.
They query I'm using right now is:
SELECT base_beta.Tipo,
base_beta.fecha_numero,
base_beta.Variedad,
base_beta.Fecha,
base_beta.alhondiga,
base_beta.corte_uno,
base_beta.corte_dos,
base_beta.corte_tres,
base_beta.corte_cuatro,
base_beta.corte_cinco,
base_beta.corte_seis,
base_beta.corte_siete,
base_beta.corte_ocho,
base_beta.corte_nueve,
base_beta.corte_diez,
base_beta.corte_once,
base_beta.corte_doce,
base_beta.corte_trece,
base_beta.corte_catorce,
base_beta.corte_quince
FROM base_beta
WHERE 1=1
AND base_beta.Tipo = 'pi'
ORDER BY base_beta.fecha_numero DESC
There are serveral columns with corte (aka prices) because every item has a random number of prices, since the fruits and vegetables has a bid system where prices decrease on every round.
For example, a tomato may start at 0,80€ and then its prices decrease to 0.76, 0.74, 0.69 and so on.
What code do I have to add to show the data of the current day and the next 6 days to complete a week?
Here are a photo of the: database content and format
Thanks, Jose.

If this defines your table schema
CREATE TABLE prices (item INT UNSIGNED, price DECIMAL(5,2), date DATETIME);
the following query will retrieve prices up to 7 days back in time
SELECT * FROM prices WHERE date > SUBDATE(CURDATE(),7) AND date <= CURDATE();
See also https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Hope this helps.

Related

My SQL Query - Get items that had there prices reduced in the last 30 days

I have a table that keeps track of inventory price updates.
CREATE TABLE pricechangelog (
id int,
SKU varchar(50),
oldSelling DOUBLE(22,2),
newSelling DOUBLE(22,2),
date DATETIME
);
I would like to get the items that had their price reduced overrall in the last 30 days,
how would I go about doing that
This could be possible by find the difference of the current timestamp and the date. DATEDIFF() Function, and the newselling value shuould be less than the oldselling
SELECT *
FROM pricechangelog
WHERE DATEDIFF(CURRENT_TIMESTAMP, date)<= 30
AND oldSelling>newSelling;

Breaking Up a Date Range by Individual Dates

I have a table with the following features: Invoice ID, billing_period_start, billing_period_end, and items_purchased during that period.
I'm looking to break out a date range by individual dates. A date range can be contained within one month, but it can also be spread across two months, unequally. This will effectively create many more records than are currently in the table. Once I have done that, I need to breakout the amount of purchased items equally among that dates of the daterange.
billing_period_start billing_period_end
-------------------- ------------------
2010-03-05 2010-03-07
2010-04-29 2010-05-05
2010-06-29 2006-08-12
billing_date
------------
2010-03-05
2010-03-06
2010-03-07
2010-04-29
2010-04-30
2010-05-01
...
2010-05-05
2010-06-29
2010-06-30
...
2010-08-12
Now that the date range is broken into individual dates, I need to take the items_purchase and divide it by the number of the days in the billing period for each date, so that I have the items_purchase_per_date.
select
invoice_line_id AS invoice_id
,items_purchased
,billing_period_start
,billing_period_end
,date_from_parts(YEAR(billing_period_start), MONTH(billing_period_start), 1) AS period1_month_start
,last_day(month_start, month) AS period1_month_end
,datediff(day, billing_period_start, billing_period_end) + 1 AS billing_period_length
from "INVOICE_DATA"
order by 1;
I'm running this on Snowflake, but can easily convert from mySQL, if someone knows that DBMS better.
The best way to handle this in a data warehouse is using a date dimension table. That is, a table that contains all the dates you need for analysis, plus any date attributes that are interesting as well, such as which week/month/quarter etc the date belongs to and so on.
Once you have table with unique rows for all relevant dates, you can more easily tackle date spine challenges like this.
For example, for your case you'd write (assuming dates is the name of your date dimension and calendar_date the name of the column containing the unique dates:
select
d.calendar_date,
i.*
from
dates d
join
invoice_data i
on d.calendar_date between i.billing_period_start and i.billing_period_end
Now you have one row per date between those start/end dates and you can do your daily billing allocation.

Selecting average prices for each of the last 30 days in SQL

Have this query that I use to get the average price of the products in a product category for each of the last 30 days:
SELECT DATE(bsbp.date) AS pricedate, UNIX_TIMESTAMP(DATE(bsbp.date)) AS unixdate,
ROUND(AVG((bsbp.price / 100) * (bc.exchangerate / 100)), 0) AS avgprice
FROM bd_shopbikesprices bsbp, bd_categoriesshopbikes bcsb, bd_shopbikes bsb,
bd_shops bs, bd_currencies bc
WHERE bsbp.shopbikeid = bcsb.shopbikeid AND bcsb.categoryid = 94
AND bsbp.shopbikeid = bsb.id AND bsb.shopid = bs.id AND bs.feedcurrencyid = bc.id
AND bsbp.price > 0
GROUP BY DATE(bsbp.date) ORDER BY pricedate DESC LIMIT 30
Problem is that the table with the prices (bsbp) only contains price changes, i.e. the last price of each product where the price was different than the previous price of the product (or where the product was new and therefore didn't have a previous price).
Like this:
shopbikeid|date|price
890061|2016-07-27 02:50:01|29999
890061|2016-07-21 03:21:51|49999
890061|2016-07-17 21:20:55|29999
890061|2016-06-30 04:41:36|49999
Currently the query takes the average new prices for each day, which isn't the actual average price since the average new prices only covers the products where the price was changed/new products.
My question is how the query should be rewritten so each daily average is the average price of all products on that day, including products where the prices was changed before that day.
Can it be done somehow with a nice query? (the database is a MySQL database)
I had a similiar case and solved it using the following approach:
Create a temporary table tmpLatestDates from your price table, in which you group by the product and use MAX(date)
Create another temporary table tmpLatestPrices: Join tmpLatestDateswith your price table on product and date, only keeping the rows from tmpLatestDates. This gives you the latest price for each product.
Run your original query on tmpLatestPrices
When you do this with large datasets you'll want to add indexes to the temporary tables after you created them. Also don't forget to drop the temporary tables after you're done.
The most practical way of handling it would be to put all queries in a stored procedure.
Edit: You can follow the same logic using subqueries, but I find the temp. table approach easier to follow plus it simplifies maintenance later on.

SQL Statement to get daily totals

I'm storing some data in a table and I want to be able to display the total data points per day on the graph. So the first graph point might be 7 for Monday, Jan 1, 2013, and then 3 for Tuesday, Jan 2, 2013...etc.
I have full time/date stamps for each of my data points in my table of SQL type datetime.
My pseudo statement looks like this, but I'm concerned since I'm using the datetime data type:
SELECT
DATE(created_at) AS create_date
COUNT(id) AS total
FROM
data_table
GROUP BY
create_date
How can I get the total data points per day, regardless of the timestamp?
Try this
SELECT
DATE(created_at) AS create_date,
COUNT(id) AS total
FROM
data_table
GROUP BY
DATE(created_at)
Best would be to start a daily cron job that stores the number of the data points for every day. So you can every day count the number between let's say 24.00.00 to 23.59.59.
If you want to count them on the fly you might have slow requests on huge data amounts, since the grouping query cannot use table index.
But maybe you can add a new table column where you store just the date additionally to the timestamp.

Need help with MySQL database (VB.NET)

I'm trying to create a system that can calculate money spend on monthly or a year. Now, roughly I have created 3 tables (actually there are 5 but 2 of them are items list and their prices so there is nothing wrong with it) on my database that is:-
(i) Daily - Field (Num, DTotal, Date) >> save all item's value by day
(ii) Monthly - Field (Num, MTotal, StartDate) >> save all values from Daily table from a starting date until the end of month of that date.
(iii) Year - Field (num, YTotal, StartDate) >> save all values from Monthly table from a staring month until the end of the year.
The Daily part I have succeeded but the problem now is with the Monthly part. I don't know how to calculate it. How am I supposed to read the Daily table from a date until another date? Let's say I want to save from 15/8/2011 until 31/8/2011. Help please.
insert into monthly (ytotal, StartDate)
select sum(Dtotal), MONTH(Date) date
group by MONTH(Date)
ON DUPLICATE KEY UPDATE
Also, make sure to put a unique index on Monthly.StartDate. That and the ON DUPLICATE KEY UPDATE clause will protect you in case the insert is run several times.
see http://dev.mysql.com/doc/refman/5.1/en/insert-select.html