timeseries averagein vertica - vertica

I have a table of stock prices over time with the fields: timestamp, price.
I could get the last value of the stock in each day like this:
SELECT slice_time, TS_LAST_VALUE(price, 'CONST') FROM StockPrices
TIMESERIES slice_time AS '1 day' over (ORDER BY timestamp)
What if I want the average price of the stock that day? Something like TS_AVG_VALUE...
Note this needs to work for any arbitrary time frame and not be hard coded for a duration of day.

check out:
http://my.vertica.com/docs/6.0.0-1/HTML/index.htm#14430.htm
I think you could just do:
SELECT avg(TS_FIRST_VALUE(bid, 'LINEAR')) avg_bid FROM Tickstore
TIMESERIES slice_time AS '2 seconds' OVER(PARTITION BY symbol ORDER BY ts);
The linearity, I think, would give you the desired averaging effect.

Related

How to get out only change record from daily level data?

I have a huge amount stock data. We are tracking every day stock level amount. My purpose is to get query which take records only when the amount is change:
Sample:
Desired result:
Try this query with subquery:
Select date_id, product,warehouse,amount
From
(
Select
date_id, product, warehouse, amount,
lag(amount) over (partition by product, warehouse order by date_id) amount_prev
From TABLENAME
) x
Where amount <> amount_prev

oracle's analytical function issue

Please let me know if the following is off topic, or not clear, or too specific, or too complex to understand. I think the following is a challenge to describe, understand and solve.
CIF=cost, insurance, frieght (basically it is the import value)
The simiplified version of input table (Import) looks like this:
enter image description here
So from January to June the value 1 is assigned to SixMonthPeriod column, and the rest of the months are given the value 2.
I then want to calculate unit price for a six period, thus I use
select SixMonthPeriod, ProductDescrip, Sum(weight), Sum (CIF), (Sum (CIF))/(Sum(weight)) as UnitPrice
from Import
group by SixMonthPeriod, ProductDescrip;
This is fine, but I then want to calculate inflation for each product (over a six month period )where I need to use lag (an oracle analytical function). The six month period has to be fixed. Thus, if the previous period for a particular product is missing, then the unit price should be zero. I want to re-begin/begin the calculation of inflation for each product. The unit price and inflation equations looks like the following, respectively:
unit price = (Sum(weight) over a six month period)/(Sum (CIF) over a six month period)
inflation = (Current Unit price - previous unit price)/(previous unit price)
I use the following SQL to calculate inflation for a six month period for each product, where the calculation begins again for each product:
select Yr, SixMthPeriod, Product, UnitPrice, LagUnitPrice, ((UnitPrice -LagUnitPrice)/LagUnitPrice) as inflation
from (select Year as Yr, SixMonthPeriod as SixMthPeriod,
ProductDescrip as product, (Sum (CIF))/(Sum(weight)) as UnitPrice,
lag((Sum (CIF))/(Sum(weight)))
over (partition by ProductDescrip order by YEAR, SixMonthPeriod) as LagUnitPrice
From Import
group by Year, SixMonthPeriod, ProductDescrip)
The problem is the inflation period is not fixed.
For example, for the result, I get the following:
enter image description here
The first two rows are fine and there should be null values because they are my first line, thus there is no LagUnitPrice and inflation.
The third line has a problem where it has taken 0.34 as the LagUnitPrice but actually it is zero (for the period 2016 where SixMthPeriod=1 for the product barley). the oracle analytical functions does not take into account missing rows (e.g. for the period 2016 where SixMthPeriod=1 for the product barley).
how do I fix this problem (if you understand me)?
I have 96 rows, thus I can export the file to excel, and use excel's formulas to fix these exceptions.
You can autogenerate missing periods with nullable price, attach them to your data and do the rest as you did:
select product, year, smp, price, prev_price, (price - prev_price) / prev_price inflation
from (
select product, year, smp, price,
lag(price) over (partition by product order by year, smp) prev_price
from (
select year, ProductDescrip product, SixMonthPeriod smp, sum(CIF)/sum(weight) price
from Import
group by year, SixMonthPeriod, ProductDescrip) a
full join (
select distinct year, productdescrip product, column_value smp
from import cross join table(sys.odcinumberlist(1, 2))) b
using (product, year, smp))
order by product, year, smp
SQLFiddle demo
Subquery b is responsible for generating all periods, you can run it separately to see what it produces.

95 percentile hourly data per day in HP Vertica

I was attempting to find the 95 percentile of all the values per hour and display them at daily level. Here is snippet of the code I am working on:
select distinct columnA
,date(COLLECTDATETIME) as date_stamp
,hour(COLLECTDATETIME) as hour_stamp
,PERCENTILE_DISC(0.95) WITHIN GROUP(order by PARAMETER_VALUE)
over (PARTITION BY hour(COLLECTDATETIME)) as max_per_day
from TableA
where
columnA = 'abc'
and PARAMETER_NAME = 'XYZ';
Right now the result set gives me the same value per hour each day, but it doesn't the 95 percentile value for a given hour per day.
Just a thought, but have you tried converting PARAMETER_VALUE into one of the data types that are accepted by the ORDER BY expression (INTEGER, FLOAT, INTERVAL, or NUMERIC)?
For example, you could try WITHIN GROUP(order by PARAMETER_VALUE::FLOAT).
You need to add an aggregate query on the top of the subquery (the percentile). Either max/min (because in each scope the percentiles are the same) percentile_disc is an analytics function but not aggregate function
SELECT dateid,
hour,
MAX(max_per_day) as max_per_day
FROM (
SELECT date(COLLECTDATETIME) AS dateid,
hour(COLLECTDATETIME) AS hour,
percentile_disc(0.95) WITHIN GROUP(order by PARAMETER_VALUE) OVER (PARTITION BY date(COLLECTDATETIME), hour(COLLECTDATETIME)) as max_per_day
WHERE ......
)
GROUP BY dateid, hour

How to add one month to month and year

I am working in oracle and new to coding and new to this site so I apologize in advance for the newbie question:
I have a script I am trying to run that will return the sum of next months' sales orders and compare that figure against our budgeted sales forecast. It was working great last month (November) when I set it up but now that it's December, I believe it's having problems figuring out that next month is a new year.
Essentially I just want to sum of our sales order records from the next month and compare that number against our forecast number.
Here is what I have so far (I'm sure I am making lots of grammatical mistakes so please be patient!)
select
"Backlog", "Forecast Amount" , round("Backlog"/"Forecast Amount",4) as "Backlog Percent"
from
(select round(sum(NVL(unit_price,0) *NVL( ship_quan,0)),2) as "Backlog"
from v_backlog_releases
where
(TO_CHAR(V_BACKLOG_RELEASES.PROMISE_DATE,'MM\YYYY') = TO_CHAR(sysdate,'MM\YYYY')+1)),
(select budamount as "Forecast Amount"
from
glbudget,
glperiods
where
glbudget.glperiods_id=glperiods.id and
TO_CHAR(GLPERIODS.START_DATE,'MM') = TO_CHAR(sysdate,'MM')+1)
The system won't let me post images of the output since I am too new. Essentially I should get something that looks like this:
Backlog | Forecast Amount | Backlog Percent
100,000 | 200,000 | .50
The backlog column is just a sum of ship quantities * price for all orders due to ship the following month.
Your issue is that for December TO_CHAR(sysdate, 'MM') + 1 is returning 13 instead of 1 of the next year. Obviously there is no month 13...
Try using ADD_MONTHS(sysdate, 1) instead and handle that result as appropriate. Best advice is to handle dates as dates instead of chars whenever possible.
Update based on comments:
Try using:
EXTRACT(MONTH FROM GLPERIODS.START_DATE) = EXTRACT(MONTH FROM ADD_MONTHS(sysdate, 1))
Documentation: https://docs.oracle.com/cd/B14117_01/server.101/b10759/functions045.htm

SQL Query to fetch data from the last 30 days?

Hi I am new to Oracle. How do I do a simple statement, for example get product id from the last 30, or 20 days purchase date?
SELECT productid FROM product
WHERE purchase_date ?
SELECT productid FROM product WHERE purchase_date > sysdate-30
The easiest way would be to specify
SELECT productid FROM product where
purchase_date > sysdate-30;
Remember this sysdate above has the time component, so it will be purchase orders newer than 03-06-2011 8:54 AM based on the time now.
If you want to remove the time conponent when comparing..
SELECT productid FROM product where purchase_date > trunc(sysdate-30);
And (based on your comments), if you want to specify a particular date, make sure you use to_date and not rely on the default session parameters.
SELECT productid FROM product where
purchase_date >
to_date('03/06/2011','mm/dd/yyyy')
And regardng the between (sysdate-30) - (sysdate) comment, for orders you should be ok with usin just the sysdate condition unless you can have orders with order_dates in the future.
Pay attention to one aspect when doing "purchase_date>(sysdate-30)": "sysdate" is the current date, hour, minute and second. So "sysdate-30" is not exactly "30 days ago", but "30 days ago at this exact hour".
If your purchase dates have 00.00.00 in hours, minutes, seconds, better doing:
where trunc(purchase_date)>trunc(sysdate-30)
(this doesn't take hours, minutes and seconds into account).
Try this : Using this you can select data from last 30 days
SELECT
*
FROM
product
WHERE
purchase_date > DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
SELECT COUNT(job_id) FROM jobs WHERE posted_date < NOW()-30;
Now() returns the current Date and Time.
select status, timeplaced
from orders
where TIMEPLACED>'2017-06-12 00:00:00'

Resources