I have sales data at the start of every month in a quarter.
Example: For 22-Q1 quarter, I have sales on 3 dates (1st Jan, 1st Feb and 1st March)
Date
Country
Region
Sales
01/01/2022
UK
EMEA
100,000
02/01/2022
UK
EMEA
170,000
03/01/2022
UK
EMEA
120,000
01/01/2022
US
AMS
90,000
02/01/2022
US
AMS
110,000
03/01/2022
US
AMS
160,000
My requirement is to extrapolate the Sales data between the 2 given dates based on difference between the 2 dates and concatenate them to the same table.
For example for 2nd Jan, I calculate the date difference between 1st Jan and 1st Feb, which is 31 days and increment Sales amount by (1/31) and for 3rd Jan, I increment Sales amount by (2/31).. so on until 31st Jan.
After the month change, the date difference needs to be recalculated between 1st Feb and 1st March and similar increment on Sales needs to be applied
You can use a UDTF to generate the rows for each day of the month along with an extrapolation of the sales.
create or replace table T1 as
select
COLUMN1::date as Date,
COLUMN2::string as Country,
COLUMN3::string as Region,
COLUMN4::number(38,2) as Sales
from (values
('01/01/2022','UK','EMEA',100000),
('02/01/2022','UK','EMEA',170000),
('03/01/2022','UK','EMEA',120000),
('01/01/2022','US','AMS',90000),
('02/01/2022','US','AMS',110000),
('03/01/2022','US','AMS',160000)
);
create or replace function EXTRAPOLATE_MONTH_TO_DAYS(MONTH_START date, VAL float)
returns table (DAY_DATE date, VAL float)
language javascript
as
$$
{
initialize: function (argumentInfo, context) {
},
processRow: function (row, rowWriter, context) {
const DAY = 86400000; // Milliseconds per day.
let firstDay = row.MONTH_START;
let lastDay = new Date(row.MONTH_START.getFullYear(), row.MONTH_START.getMonth() + 1, 0);
let daysInMonth = lastDay.getDate();
let valPerDay = row.VAL / daysInMonth;
let sum = 0;
let curDate = row.MONTH_START;
for (let i = 1; i <= daysInMonth; i++) {
sum += valPerDay;
rowWriter.writeRow({DAY_DATE:new Date(firstDay.getTime()+DAY*(i-1)),VAL:sum});
}
},
}
$$;
select DATE
,COUNTRY
,REGION
,SALES
,DAY_DATE
,round(VAL,2)::number(38,2) EXTRAPOLATED_RUNNING_TOTAL
from T1, table(EXTRAPOLATE_MONTH_TO_DAYS(DATE, SALES::float) over (partition by COUNTRY, REGION order by DATE))
;
First five rows:
DATE
COUNTRY
REGION
SALES
DAY_DATE
EXTRAPOLATED_RUNNING_TOTAL
2022-01-01
US
AMS
90000
2022-01-01
2903.23
2022-01-01
US
AMS
90000
2022-01-02
5806.45
2022-01-01
US
AMS
90000
2022-01-03
8709.68
2022-01-01
US
AMS
90000
2022-01-04
11612.90
2022-01-01
US
AMS
90000
2022-01-05
14516.13
Related
I have table of EMPLOYEE , in which I need to show the salary from this month to this month .
Suppose I have dates eg. from date 17/01/2020 and to date 18/02/2020 I need monthly data between these two dates like from 17th JAN to 30th JAN one data and from 1st FEB to 28th FEB.
Please suggest some query i trying it but not able to fetch between two dates.
select add_months (to_date(from_date,'dd/mm/yyyy' ), - (level-1)), 'Mon yy') as MONTH,SALARAY from EMPLOYE_BG where CREATED_DATE between TO_DATE('17/01/2020','dd/mm/yyyy')
and to_date('10/03/2020','dd/mm/yyyy')
O/P:
MONTH SALARY
----------------
JAN-20 30000
FEB-20 50000
MAR-20 60000
like this i am expecting the result
SELECT * FROM EMPLOYE_BG
SALARY EMPNAME CREATED_DATE
---------------------------------
30000 JACK 07/01/2020
30000 SWETA 08/01/2020
30000 RAM 08/01/2020
40000 JOHN 01/02/2020
60000 SIMON 10/03/2020
70000 KIRA 11/04/2020
this is table details
I have transactions table with columns id, user_id, currency, amount and created_at;
I want to write function to check in last x days transaction with exist amount repeated or not.
For example user makes transaction per 200$ in 5 days, and 6th days wants to make transaction in 250$. Function have to check did user make transaction in last 5 days per 250$ or not. In this example function have to return false. Because user breaks rule.
If user want to make transaction with 200$ function have to return true;
I have tried with
select count(*) from "transactions" where "created_at" >= NOW()- INTERVAL '5 DAY' and "amount"=250 and "currency" = "USD"
but this gives me incorrect answer, becouse if user makes a transaction twise a day, this function calculates 5 items in 4 day. If n transactions in a day I have to calculate it 1 transaction.
So:
id user_id currency amount created_at
1 1 USD 200 2021-05-15 16:00:01
2 1 USD 200 2021-05-16 18:05:28
3 1 USD 200 2021-05-17 11:33:55
4 1 USD 200 2021-05-18 12:00:01
5 1 USD 200 2021-05-18 13:15:01
6 2 USD 250 2021-05-15 16:00:01
7 2 USD 250 2021-05-16 18:05:28
8 2 USD 250 2021-05-17 11:33:55
9 2 USD 250 2021-05-18 12:00:01
10 2 USD 250 2021-05-19 13:15:01
with this data, query have to return 4 items for user with id 1 and amount 200. Have to return 5 items for user with id 2 and amount 250
I think you just want count(distinct). You seem to want different values for each user, so that suggests group by as well:
select user_id, count(distinct created_at::date) as num_days
from "transactions"
where created_at >= NOW()- INTERVAL '5 DAY' and
amount = 250 and
currency = 'USD'
group by user_id;
See table A. There are number of sales per date. The dates are not continuous.
I want table B where it gives the sales moves per the previous date in the dataset.
I am trying to do it in SQL but get stuck. I can do an individual day on day difference by entering the date but I want one where I don't need to enter the dates manually
A
Date Sales
01/01/2019 100
05/01/2019 200
12/01/2019 50
25/01/2019 25
31/01/2019 200
B
Date DOD Move
01/01/2019 -
05/01/2019 +100
12/01/2019 -150
25/01/2019 -25
31/01/2019 +175
Use lag():
select t.*,
(sales - lag(sales) over (order by date)) as dod_move
from t;
I have date field and from that date field i am trying to extract only weekends i.e. in my case Saturday and Sunday is weekend.
So how can i extract weekends from date?
If below dates are in weekend then should be like this:
Date day working hours
01/01/2019
02/01/2019
03/01/2019
04/01/2019
05/01/2019 weekend 24
06/01/2019 weekend 87
07/01/2019
08/01/2019
09/01/2019
10/01/2019
Data link: https://www.dropbox.com/s/xaps82qyyo6i0fa/ar.xlsx?dl=0
You can use WeekDay functon. This function accepts date value/field and return the day of the week. The returned value is in dual format - day name and day number.
So you can create additional field that checks if the day number is >= 5 (day numbers are starting from 0 so Saturday = 5 and Sunday = 6)
RawData:
LOAD
AttendanceDay,
if(WeekDay(AttendanceDay) >= 5, 1, 0) as isWeekend,
Employee_ID,
WorkingHours
FROM
[..\Downloads\ar.xlsx]
(ooxml, embedded labels, table is Attendances_20191119_0838)
;
Resulted table after the reload:
I have plotted a graph of months versus business turnover, but the months are not in order. They are rather alphabetically ordered. I want them to be ordered as in a financial year i.e. april, may, june......march.
This is how the dataframe is.
Month_name CASH/TPA Total
April CASH 2184074.0
August CASH 1780238.0
December CASH 1176889.0
Use ordered categoricals with order defined in parameter categories:
months = ['April','May','June','July','August',
'September','October','November',
'December','January','February','March']
df['Month_name'] = pd.CategoricalIndex(df['Month_name'], ordered=True, categories=months)
If need sorting by Month_name:
df1 = df.sort_values('Month_name')
Or by both columns:
df2 = df.sort_values(['CASH/TPA', 'Month_name'])
Or if necessary, pivoting:
df3 = df.pivot('Month_name','CASH/TPA','Total')
df['Month_name']=pd.to_datetime(df.Month_name, format='%B', errors='coerce').dt.month.map("{:02}".format)
Month_name CASH/TPA Total
0 April CASH 2184074.0
1 August CASH 1780238.0
2 December CASH 1176889.0
Month_name CASH/TPA Total
0 04 CASH 2184074.0
1 08 CASH 1780238.0
2 12 CASH 1176889.0