DAX-How to achieve a year-to-date per category? - dax

My problem is the following:
I have a table like this one below:
Date Category Value Movment Value
2019-01-01 105 1000 1000
2019-02-05 110 1200 200
2019-03-25 100 800 -400
2019-03-28 100 700 -100
2019-04-15 95 1300 600
To get the value at date, I can calculate a year-to-date on the Movment Value column (because the Value column is not additive with respect to Date column).
Things get worse when I filter on Category column. The year-to-date gives me these values per category which is correct:
Category: 95 100 105 110
YTD : 600 -500 1000 200
But the result I am looking for is:
Category: 95 100 105 110
YTD : 1300 700 1000 1200
What I tried is this formula:
IF(NOT(ISFILTERED([Category])); [Movment Value YTD]; [Movment Value Reset Per Category YTD]),
where [Movment Value Reset Per Category] is the year-to-date of reset movment, i.e.
Date Category Value Movment Value Movment Value Per Category
2019-01-01 105 1000 1000 1000
2019-02-05 110 1200 200 1200
2019-03-25 100 800 -400 800
2019-03-28 100 700 -100 -100
2019-04-15 95 1300 600 1300
It works, but if we use multiple dimensions to filter on, it could become very complicated to manage.
Do you have an idea, how I can achieve this "special" YTD per category without having to manage all cases ?
Thank you for your inputs.
Marco

Related

Replace null values with the most recent value in a time series

I have this series (notice the holes in the dates):
Date
Value
2019-12-31
100
2020-01-02
110
2020-01-05
120
2020-01-07
125
2020-01-08
130
And I need to get this one:
Date
Value
2019-12-31
100
2020-01-01
100
2020-01-02
110
2020-01-03
110
2020-01-04
110
2020-01-05
120
2020-01-06
120
2020-01-07
125
2020-01-08
130
Notice that the rows with bold font didn't exist in the first table and the values are forward filled from the most recent value available.
To get this done:
I created a dummy calendar with the List.Dates() function.
I merged this calendar with the first table obtaining this:
Date
Value
2019-12-31
100
2020-01-01
null
2020-01-02
110
2020-01-03
null
2020-01-04
null
2020-01-05
120
2020-01-06
null
2020-01-07
125
2020-01-08
130
Then I created a function that took a date as a parameter which filtered the first table and with the function List.Last() took the last non-null value and placed it in the row of the third table instead of the null.
It works quite well, but I find it too slow. For each row the function must be called to scan the table for the most recent value available.
Is there a quicker way to perform this?

Dynamic column value to be set as next row's another column value in Oracle [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am new to Oracle and I would like to form an Oracle query:
Id CrLmt Type Unit Price Amount Prev_bal NewBal
5-00001 100000 Sell 100 150 15000 100000 85000
Buy 75 600 45000 85000 130000
Buy 85 550 46750 130000 176750
Sell 60 1000 60000 176750 116750
5-00002 90000 Sell 100 400 40000 90000 50000
Buy 550 300 165000 50000 215000
Sell 300 1000 300000 215000 -85000
My conditions are as follows:
ID and CrLmt are combination and its subsequent rows come under this ID, CrLmt combination.
For every ID, CrLmt combination, the CrLmt will be assigned in Prev_Bal column, rest of the rows will have a calculation
Based on Buy/Sell in Type column, the values in Amount and Prev_Bal will be added or subtracted and the resultant value should be displayed in NewBal (dynamic) column
If the Type is "Sell" then the value in PrevBal should be subtracted with Amount column value and if the Type is "Buy" then then the value in PrevBal should be added with Amount column value and the resultant value should be displayed in NewBal (dynamic) column in the corresponding row
The value obtained in NewBal column in row 1 should be displayed in row 2 Prev_Bal column for 2nd row's calculation and so on.
If any negative value occurs in NewBal column the same needs to be carried out to next calculations.
I tried using LAG function to get previous values but doesn't know how to get a dynamic column's (NewBal) values on the go.
Here is a little example that you will have to adapt to your current structure. You will need a date on your transaction for the order clause of the sum.
all you need is a running sum to which you will either add the credit limit for the new_balance or to which you will take the previous row for the old_balance
--TEST DATA
CREATE TABLE credit_limit ( id varchar2(10), crlmt number );
CREATE TABLE transactions (transaction_type varchar2(4), unit number, price number, amount number, crlmt_id varchar2(10), date_transaction date );
INSERT INTO credit_limit values ('5-00001',100000);
INSERT INTO credit_limit values ('5-00002',90000);
INSERT INTO transactions values ('Sell',100,150,15000,'5-00001',sysdate-4);
INSERT INTO transactions values ('Buy',75,600,45000,'5-00001',sysdate-3);
INSERT INTO transactions values ('Buy',85,550,46750,'5-00001',sysdate-2);
INSERT INTO transactions values ('Sell',60,1000,60000,'5-00001',sysdate-1);
INSERT INTO transactions values ('Sell',100,400,40000,'5-00002',sysdate-3);
INSERT INTO transactions values ('Buy',550,300,165000,'5-00002',sysdate-2);
INSERT INTO transactions values ('Sell',300,1000,300000,'5-00002',sysdate-1);
--The query
select cr.id, cr.crlmt, tr.transaction_type, tr.unit, tr.price, tr.amount,
NVL(cr.crlmt + SUM(tr.amount*decode(tr.transaction_type,'Sell',-1,'Buy',1))
OVER (partition by cr.id order by cr.id, tr.date_transaction
rows between unbounded preceding and 1 preceding ),Cr.crlmt) old_bal,
cr.crlmt + SUM(tr.amount*decode(tr.transaction_type,'Sell',-1,'Buy',1))
OVER (partition by cr.id order by cr.id, tr.date_transaction
rows between unbounded preceding and current row ) new_bal
from
credit_limit cr
JOIN
transactions tr
ON cr.id=tr.crlmt_id
order by cr.id, tr.date_transaction
result :
ID CRLMT TRAN UNI PRICE AMOUNT OLD_BAL NEW_BAL
5-00001 100000 Sell 100 150 15000 100000 85000
5-00001 100000 Buy 75 600 45000 85000 130000
5-00001 100000 Buy 85 550 46750 130000 176750
5-00001 100000 Sell 60 1000 60000 176750 116750
5-00002 90000 Sell 100 400 40000 90000 50000
5-00002 90000 Buy 550 300 165000 50000 215000
5-00002 90000 Sell 300 1000 300000 215000 -85000

Tables Summary into single table in laravel

I have two tables named 'Customers' and 'Committeetables' in mysql database. They have following columns
Table: Customer
nd Name FatherName Cell# AdvanceAmount
25 Waseem Asghar 0302 2500
30 Ramzan Khan 0303 3500
35 Rana Ali 0307 2000
Table: CommitteeTables
nd Amount RecievingDate DrawDate
25 1500 2-10-15 10-10-15
30 1500 2-10-15 10-10-15
25 1500 3-10-15 10-11-15
30 1500 3-10-15 10-11-15
35 1500 3-10-15 10-11-15
A Column 'nd' in 'Customers' table is primary key and in 'CommitteeTables' table is foreign key. It means 'Customers' table joins with 'ComitteeTables' table through 'nd' column.
Expected Result table should be as under:
nd Name Father Name Cell# Advance Amount Balance
25 Waseem Asghar 0302 25000 3000 22000
30 Ramzan Khan 0303 35000 3000 32000
32 Rana Ali 0307 20000 1500 18500
----------------------------------------------------------------------------
total 80000 7500 72500
I am using Laravel 5 and HTML, Bootstrap. I need this result in Laravel 5. I shall be really thankful if someone help me to solve my problem.
Thanks
Waseem
This is not at all a Laravel question. It's a general SQL question.
Something like this:
SELECT nd, Name, FatherName, Cell#, AdvanceAmount as Advance,
(SELECT SUM(Amount) FROM CommitteeTables WHERE CommitteeTables.nd=Custoemr.nd) as Amount, Advance-Balance AS Balance
FROM Customer;
I'm not entirely sure that's correct but you can try it and fix any errors. As Bogdan suggests you should try something first then come back here with any problems that you have.

Aggregating the table from many rows to one

I have a table with data as follows:
Name opening receipt transfer closing
abcd 1000 40 30 1010
efg 256 109 219 146
hjk 9356 210 210 9356
mnp 2000
I need is a result like this -
opening_abcd receipt_abcd transfer_abcd closing_abcd opening_efg receipt_efg .....
1000 40 30 1010 256 109 .....
What I have tried till now is to create multiple views one by one having the one row values like -
select opening opening_abcd, receipt receipt_abcd, transfer transfer_abcd, closing closing_abcd
from this_table
where name = 'abcd'
and similarly for others and then I have merged them together by using JOIN.
Is there a solution possible if I can select all of them in one query or any other way which is better than mine?

How to structure a db table to store ranges like 0;20;40;60;80 or 0;50;100;150;200;250;... so on

I want to store the below range in a table, the number of items in template01 is 6, second is 4. How can we structure the table to store this information. Displaying these values as comma separated or having one column for each range values stated would be my last option. Can you help on how to structure the table/tables to store the below said information.
Template01 0 10 20 30 40 50
Template02 0 50 100 150
Template03 0 100 200 300 400 500 600
Basically, I want to store these ranges as templates and use it later for saying if the luggage weight is from 0 - 10, it will cost $5 per Kg, if its 10 - 20, it will cost $4.8 per Kg etc
This is how the template will be used,
Domain: XYZ
Template01 0 10 20 30 40 50
Increment01% 125% 120% 115% 110% 105% 100%
Domain: ABC, am using or picking the same template 'Template01' but Increment%
will be different for different domain, hence
Template01 0 10 20 30 40 50
Increment02% 150% 140% 130% 120% 110% 100%
Idea is, I want to store Template of weight breaks and later I want to associate with different Increment%. Thus when the user chooses a weight break template, all the increment% values applicable or configured for that template can be shown for the user to choose one.
Template01 0 10 20 30 40 50
Increment01% 125% 120% 115% 110% 105% 100% [Choice 1]
Increment02% 150% 140% 130% 120% 110% 100% [Choice 2]
Standard approach is:
Template_Name Weight_From Weight_To Price
------------- ----------- --------- -----
Template01 0 10 5
Template01 10 20 4.8
...
Template01 40 50 ...
Template01 50 (null) ...
Template02 0 50 ...
...
Template03 500 600 ...
Template03 600 (null) ...
For a normalised schema you'd need to have tables for the Template, for the Increment, for the Template Weights, and for the Increment Factors.
create table luggage_weight_template (
luggage_weight_template_id number primary key,
template_name varchar2(100) unique);
create table luggage_increment (
luggage_increment_id number primary key,
increment_name varchar2(100),
luggage_weight_template_id references luggage_weight_template(luggage_weight_template_id));
create table template_weight (
template_weight_id number primary key,
luggage_weight_template_id references luggage_weight_template(luggage_weight_template_id),
weight_from number not null);
create table increment_factor (
increment_factor number primary key,
increment_id references luggage_increment(luggage_increment_id),
template_weight_id references template_weight(template_weight_id));

Resources