DB2 - difference between two timestamp in days - db2

how to get exact difference between two timestamp in days in DB2. I mean if one date is FROM_DATE=5/6/2015 2:22:27.000000 PM and TO_DATE=3/30/2015 2:33:52.000000 PM, then the timestamp difference should show 36 days. I tried using below
((24*DAYS(From_Date)+MIDNIGHT_SECONDS(From_Date)/3600) -
(24*DAYS(To_Date)+MIDNIGHT_SECONDS(To_Date)/3600))/(24)
But this is giving me the difference as 37 days.

What about
SELECT days_between ('2015-05-06-02.22.27.000000', '2015-03-30-02.33.52.000000')
FROM SYSIBM.sysdummy1
It returns 36.

Wrong formula. Check out the following.
SELECT
FROM_DATE, TO_DATE
,
(
(24*DAYS(From_Date)+MIDNIGHT_SECONDS(From_Date)/3600)
- (24*DAYS(To_Date)+MIDNIGHT_SECONDS(To_Date)/3600)
)/24 AS D1
,
(
(DAYS(From_Date)*bigint(86400) + MIDNIGHT_SECONDS(From_Date))
- (DAYS(To_Date) *bigint(86400) + MIDNIGHT_SECONDS(To_Date))
)/86400 AS D2
FROM
(
VALUES
(TIMESTAMP('2015-05-06-14.22.27'), TIMESTAMP('2015-03-30-14.33.52'))
, (TIMESTAMP('2015-03-31-14.22.27'), TIMESTAMP('2015-03-30-14.33.52'))
, (TIMESTAMP('2015-04-01-14.22.27'), TIMESTAMP('2015-03-30-14.33.52'))
) T(FROM_DATE, TO_DATE);
|FROM_DATE |TO_DATE |D1 |D2 |
|--------------------------|--------------------------|-----------|--------------------|
|2015-05-06-14.22.27.000000|2015-03-30-14.33.52.000000|37 |36 |
|2015-03-31-14.22.27.000000|2015-03-30-14.33.52.000000|1 |0 |
|2015-04-01-14.22.27.000000|2015-03-30-14.33.52.000000|2 |1 |

Related

how can I generate 6 month dates from a specific date

I have a table pqdf.
which have Effective_Date column, first I will do distinct of Effective_Date.
now from this date I want to generate 6 months dates,
if my start date is 2022-01-01 then my table last row value will be 2022-06-30. and total row count be around 181 rows
+----------------+
| Effective_Date |
+----------------+
| 2022-01-01 |
| 2022-01-01 |
| 2022-01-01 |
+----------------+
please help
I tried below but query but its not working.
select explode (sequence( first_value(to_date('Effective_Date'))), to_date(DATEADD(month, 6, Effective_Date)), interval 1 day) as date from pqdf
See if this works. If it doesn't, can you please also provide the error message that you are seeing?
WITH pqdf AS (
SELECT "2022-01-01" AS Effective_Date
)
SELECT
EXPLODE(SEQUENCE(
DATE(Effective_Date),
TO_DATE(DATEADD(MONTH, 6, DATE(Effective_Date))),
INTERVAL 1 DAY)
) AS date
FROM
pqdf

Calculate Average of Price per Items per Month in a Few Years Postgresql

I have this table inside my postgresql database,
item_code | date | price
==============================
aaaaaa.1 |2019/12/08 | 3.04
bbbbbb.b |2019/12/08 | 19.48
261893.c |2019/12/08 | 7.15
aaaaaa.1 |2019/12/17 | 4.15
bbbbbb.2 |2019/12/17 | 20
xxxxxx.5 |2019/03/12 | 3
xxxxxx.5 |2019/03/18 | 4.5
how can i calculate the average per item, per month over the year. so i get the result something like:
item_code | month | price
==============================
aaaaaa.1 | 2019/12 | 3.59
bbbbbb.2 | 2019/12 | 19.74
261893.c | 2019/12 | 7.15
xxxxxx.5 | 2019/03 | 3.75
I have tried to look and apply many alternatives but i am still not get the point, would really appreciate your help because i am new to postgresql.
I don't see how the question relates to a moving average. It seems you just want group by:
select item_code, date_trunc('month', date) as date_month, avg(price) as price
from mytable
group by item_code, date_month
This gives date_month as a date, truncated to the first day of the month - which I find more useful that the format you suggested. But it you do want that:
to_char(date, 'YYYY/MM') as date_month

Select the maximum rows of sorted subgroups

Using PostgreSQL 11, I have a table containing a DAY and MONTH_TO_DAY entry for each day of every month. I would like to select the most recent MONTH_TO_DAY entry for each account.
My table is:
+------+------------+--------------+------------+--------------------------+
|id |account |code |interval |timestamp |
+------+------------+--------------+------------+--------------------------+
|387276|ALPBls6EsP |52 |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387275|ALPBls6EsP |52 |DAY |2020-09-01 01:05:00.000000|
|387272|YkON8lk8A8 |25 |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387271|YkON8lk8A8 |25 |DAY |2020-08-01 01:05:00.000000|
|387273|ALPBls6EsP |32 |MONTH_TO_DAY|2020-08-31 01:05:00.000000|
|387274|ALPBls6EsP |32 |DAY |2020-08-31 01:05:00.000000|
|387272|ALPBls6EsP |27 |MONTH_TO_DAY|2020-08-30 01:05:00.000000|
|387271|ALPBls6EsP |27 |DAY |2020-08-30 01:05:00.000000|
+------+------------+--------------+------------+--------------------------+
If it helps, the entries are always in descending order timewise.
In a query asking for all accounts, since the 31st is the last day of 08 and the 1st is the most recent entry of 09, my expected output would be
+------+------------+--------------+------------+--------------------------+
|id |account |code |interval |timestamp |
+------+------------+--------------+------------+--------------------------+
|387276|ALPBls6EsP |52 |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387272|YkON8lk8A8 |25 |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387273|ALPBls6EsP |32 |MONTH_TO_DAY|2020-08-31 01:05:00.000000|
+------+------------+--------------+------------+--------------------------+
I was thinking I'd like to group entries by month (truncate the dd/hh/ss), and then select the row with the maximum timestamp in each group. I can get the right rows with this but I can't figure out how to get any of the other fields.
SELECT max(timestamp)
FROM mytable
GROUP BY date_trunc('month', mytable.timestamp);
I also thought I could use distinct on something like the below, but I'm not too familiar with distinct on or date_trunc and I can't figure out how to use them together.
SELECT distinct on (timestamp)
*
FROM mytable
ORDER BY date_trunc('month', mytable.timestamp)
You do want distinct on, but you want to apply it to the account:
select distinct on (account) *
from mytable
where interval = 'MONTH_TO_DAY'
order by account, timestamp desc;
If you want the latest by account by month, then this should work:
select distinct on (date_trunc('month', timestamp), account) *
from mytable
where interval = 'MONTH_TO_DAY'
order by date_trunc('month', timestamp), account, timestamp desc;

How to calculate the AVG time stamp for last one week

I am trying to calculate the AVG timestamp for last 7 days in Snowflake database.
Data type is VARCHAR and below is the sample data.
LOAD_TIME VARCHAR(10) -
Sample Data:
LOAD_TIME (HHMM)
1017
0927
0713
0645
1753
2104
1253
If you convert these values to epoch_seconds, it's possible to calculate the average:
select to_varchar(to_timestamp(avg(date_part(epoch_second,to_timestamp(load_time,'HH24MI')))), 'HH24MI') as average
from values
('1017'),('0927'),('0713'),('0645'),('1753'),('2104'),('1253') tmp (load_time);
+---------+
| AVERAGE |
+---------+
| 1213 |
+---------+

SQL calculating stock per month

I have specific task, and don't know how to realize it. I hope someone can help me =)
I have stock_move table:
product_id |location_id |location_dest_id |product_qty |date_expected |
-----------|------------|-----------------|------------|--------------------|
327 |80 |84 |10 |2014-05-28 00:00:00 |
327 |80 |84 |10 |2014-05-23 00:00:00 |
327 |80 |84 |10 |2014-02-26 00:00:00 |
327 |80 |85 |10 |2014-02-21 00:00:00 |
327 |80 |84 |10 |2014-02-12 00:00:00 |
327 |84 |85 |20 |2014-02-06 00:00:00 |
322 |84 |80 |120 |2015-12-16 00:00:00 |
322 |80 |84 |30 |2015-12-10 00:00:00 |
322 |80 |84 |30 |2015-12-04 00:00:00 |
322 |80 |84 |15 |2015-11-26 00:00:00 |
i.e. it's table of product moves from one warehouse to second.
I can calculate stock at custom date if I use something like this:
select
coalesce(si.product_id, so.product_id) as "Product",
(coalesce(si.stock, 0) - coalesce(so.stock, 0)) as "Stock"
from
(
select
product_id
,sum(product_qty * price_unit) as stock
from stock_move
where
location_dest_id = 80
and date_expected < now()
group by product_id
) as si
full outer join (
select
product_id
,sum(product_qty * price_unit) as stock
from stock_move
where
location_id = 80
and date_expected < now()
group by product_id
) as so
on si.product_id = so.product_id
Result I have current stock:
Product |Stock |
--------|------|
325 |1058 |
313 |34862 |
304 |2364 |
BUT what to do if I need stock per month?
something like this?
Month |Total Stock |
--------|------------|
Jan |130238 |
Feb |348262 |
Mar |2323364 |
How can I sum product qty from start period to end of each month?
I have just one idea - it's use 24 sub queries for get stock per each month (ex. below)
Jan |Feb | Mar |
----|----|-----|
123 |234 |345 |
End after this rotate rows and columns?
I think this's stupid, but I don't know another way... Help me pls =)
Something like this could give you monthly "ending" inventory snapshots. The trick is your data may omit certain months for certain parts, but that part will still have a balance (ie 50 received in January, nothing happened in February, but you still want to show February with a running total of 50).
One way to handle this is to come up with all possible combinations part/dates. I assumed 1/1/14 + 24 months in this example, but that's easily changed in the all_months subquery. For example, you may only want to start with the minimum date from the stock_move table.
with all_months as (
select '2014-01-01'::date + interval '1 month' * generate_series(0, 23) as month_begin
),
stock_calc as (
select
product_id, date_expected,
date_trunc ('month', date_expected)::date as month_expected,
case
when location_id = 80 then -product_qty * price_unit
when location_dest_id = 80 then product_qty * price_unit
else 0
end as qty
from stock_move
union all
select distinct
s.product_id, m.month_begin::date, m.month_begin::date, 0
from
stock_move s
cross join all_months m
),
running_totals as (
select
product_id, date_expected, month_expected,
sum (qty) over (partition by product_id order by date_expected) as end_qty,
row_number() over (partition by product_id, month_expected
order by date_expected desc) as rn
from stock_calc
)
select
product_id, month_expected, end_qty
from running_totals
where
rn = 1