I want to create a new Custom Column in AG grid which will display the calculated value of another column together with the value of the column in the previous row.
We have created lots of calculated columns in AdapTable but i cannot work out how do this.
In our example we have a Price and a Date Column and a Running Price Calculated Column.
For the row where Date is Today, I want to the value in the Running Price column to be 'Price' in this Row plus whatever the Running Price value is in the Row where Date is Yesterday.
And for yesterday's row I want Running Price to include the value for 2 days ago. And so on.
Perhaps this example will help explain:
Price | Date | Running Price
5 | 2 Days Ago | 10
7 | Yesterday | 17
9 | Today | 26
If I can do this without needing to sort AG Grid on the Date column then even better as my users like to do their own sorts and I don't want it to break the running total.
Yes, this can be done fairly easily in AdapTable.
You need to use what it calls an AggregatedScalarQuery.
Assuming that the columns in your grid are called 'Price', and 'MyDate' then the Expression for the 'RunningPrice' Calculated Column will be something like:
CUMUL(SUM([Price]), OVER([MyDate]))
See more at: https://docs.adaptabletools.com/guide/adaptable-ql-expression-aggregation-scalar#cumulative-aggregation
Edit: I should add that you dont need to sort the 'MyDate' column as per your initial message, since OVER will run over the dates in natural sort order. So your users can continue to sort AG Grid how they like without it affecting your Calculated Column.
Related
I want to build a grid that displays the number of hours an individual has worked where each column represents one day. Each day column should be inside a month column. In the gui I can select a start date and the grid should display one month -1 day worth of days, e.g.:
| January | February |
|Day6|.....|Day31|Day1|.......|Day5|
I have tried to delete the days inside a month column using destroy() on each day column, but when when the last day column is destroyed, the parent column (month) is also destroyed automagically (can I prevent this?).
I have also tried to delete the month columns and add new month columns containing day columns but this results in a very strange behavior, se example:
If i begin with this:
| January | February |
|Day6|.....|Day31|Day1|.......|Day5|
and delete January and February with destroy(), and straight after add new months containing the correct number of days I end up with duplicate of days in the grid like this:
| January | February |
|Day6|.....|Day31|Day6|.....|Day31|Day1|.......|Day5|Day1|.......|Day5|
As if the month column was never destroyed or as if the column was destroyed but the view is not updated correctly.
So to the question. What is the correct/best way to delete and add columns at runtime with the following requirements:
(At runtime when selecting a new start date:)
Delete month column OR all day columns inside the month column.
Create a new month column and populate with correct number of days OR add new day columns to the month column.
Thanks in advance!
I am trying to remove duplicates from the Ticket field in my database but I want to remove the duplicates that have older dates. example,
Ticket | Date
MG17000 | 1/1/2017
MG17000 | 1/1/2018
MG17010 | 1/1/2018
so I want the answer to be
MG17000 | 1/1/2018
MG17010 | 1/1/2018
I used countd(Ticket) but it does not remove the right tickets(it removes the ticket that corresponds to 1/1/2018 instead of 1/1/2017). any suggestions on how to perform this task.
Thanks!
Try this:
Create formula [Rank - Date] with below code:
RANK_UNIQUE((MAX(SPLIT([database field],'|',2))))
//This will create a values for every ticket
Now one more formula to filter only date with max value and drag to filter and select True
[Rank - Date]=1
You should be able to get required data
Use a level-of-detail (LOD) calculation. Create the calculation with this formula and it will give you the number of records per ticket, regardless of what dimensions you have on rows and shelves.
{FIXED [ticket] : count([date])}
If you have any date filtering and you want the calculation to count tickets outside the date filter range, switch FIXED to INCLUDE.
Drag that as one of you measures. Then use the max([date]) to show the most recent date.
From the sample data you showed in the question, you will see something like
MG17000 1/1/2018 2
MG17010 1/1/2018 1
I had the following question which I just can't wrap my head around it to do it in a neat way.
I want to create a line graph with three lines. We call it a budget snake.
Created sales orders (black)
Invoiced orders (green)
Daily targets (red)
This per salesperson. The creation of this graph for the created and invoiced orders is easy as these are all on a daily granularity so creating the line graph is easy.
I just struggle how to create/generate such a line for the targets.
In this case, I manually created a table with date - salesperson - daily target
Eg.
Which is very cumbersome. What I would like to be able to do is
create a table on a monthly level for each salesperson and that
PowerBI can "generate/calculate" the daily target in such a way that
I can graph the red line without all the hassle of creating it for
each salesperson manually.
The input would be something like this
+-----------+----------+--------------+--------+----------------+--------------+---------------+
| Date | Month | Salesperson | Branch | Monthly Target | Daily Target | Business days |
+-----------+----------+--------------+--------+----------------+--------------+---------------+
| 1/01/2017 | January | salesperson1 | test | 73529 | 4325 | 17 |
| 1/02/2017 | February | salesperson1 | test | 73529 | 4325 | 20 |
+-----------+----------+--------------+--------+----------------+--------------+---------------+
I have a date dimension table so on my graph I have the date as the x-axis and then the runningorders/runningsales as the y-axis but I would something like a daily runningtarget so that the red line is nicely going with the orders and sales.
I had a look at this pattern but I just cannot figure out how this can generate
a line graph.
https://www.daxpatterns.com/budget-patterns/
So somehow, I guess I would need something which generates this first table with the second table as input. I tried some measures in Dax but none of them give me the cumulative steps for each day. It mostly just shows me the value.
These are the measures I use for the other lines. This works nicely when changing the date filters.
Running sales
RunningTotalSales = CALCULATE(sum(vw_invoice_trn_summary[NetInvoiceValue]),
FILTER(ALLSELECTED(DimTime),DimTime[Date] <= MAX(DimTime[Date])))
Running orders
RunningTotalOrders = CALCULATE(sum(vw_orders_raised[OrderTotal]),FILTER(ALLSELECTED(DimTime),DimTime[Date] <= MAX(DimTime[Date])))
In my current manual solution, the full year though does not work well with the targets line as I am not sure I do it right.
UPDATE
So thinking further about this. It feels like I just need to be able to create a table with a date - daily target - salesperson. based on the monthly targets but not sure how you can do that in power bi. Ideally, you can just add/remove a salesperson and that specific table gets regenerated.
I have two solutions to this. One using DAX and one using the query editor.
DAX Solution:
1. Create a calendar table that has all the dates you need.
If Targets is the table containing your monthly targets, create a new table using a formula like this:
Calendar = CALENDAR(EOMONTH(MIN(Targets[Date]),-1)+1,EOMONTH(MAX(Targets[Date]),0))
2. Create a new table DailyTargets as a cross join of your dates and salespersons.
The CROSSJOIN function creates a row for each date and salesperson combination:
DailyTargets = CROSSJOIN(VALUES('Calendar'[Date]),VALUES(Targets[Salesperson]))
3. Create a calculated column for your daily targets.
I do this by looking up the monthly target and dividing by the number of days in the month:
DailyTarget = DIVIDE(
LOOKUPVALUE(Targets[MonthlyTarget],
Targets[Month], FORMAT(DailyTargets[Date],"mmmm"),
Targets[Salesperson], DailyTargets[Salesperson]),
DAY(EOMONTH(DailyTargets[Date],0)))
Now you have a daily target for each date and each salesperson.
PowerQuery Solution:
1. Create a calendar table that has all the dates you need.
Create a blank query and use the following code:
= List.Dates(List.Min(Targets[Date]),
Duration.Days(Date.EndOfMonth(List.Max(Targets[Date]))
- List.Min(Targets[Date])) + 1,
#duration(1,0,0,0))
2. Convert this list to a table.
Click on "To Table" under the Transform tab and rename the column from "Column1" to "Date".
3. Create a custom column for the month name.
You can use the formulaDate.MonthName([Date]) for this.
4. Merge this query with the Targets table (joining on the Month columns).
5. After merging, expand the Salesperson and MonthlyTarget columns.
6. Create the daily target by dividing the monthly target by the number of days in the month.
You can use the formula [MonthlyTarget]/Date.DaysInMonth([Date]) for this.
The entire query should look like this:
let
Source = List.Dates(List.Min(Targets[Date]), Duration.Days(Date.EndOfMonth(List.Max(Targets[Date])) - List.Min(Targets[Date])) + 1, #duration(1,0,0,0)),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Renamed Columns" = Table.RenameColumns(#"Converted to Table",{{"Column1", "Date"}}),
#"Added Custom" = Table.AddColumn(#"Renamed Columns", "Month", each Date.MonthName([Date])),
#"Merged Queries" = Table.NestedJoin(#"Added Custom",{"Month"},Targets,{"Month"},"Targets",JoinKind.LeftOuter),
#"Expanded Targets" = Table.ExpandTableColumn(#"Merged Queries", "Targets", {"Salesperson", "MonthlyTarget"}, {"Salesperson", "MonthlyTarget"}),
#"Added Custom1" = Table.AddColumn(#"Expanded Targets", "DailyTarget", each [MonthlyTarget]/Date.DaysInMonth([Date]))
in
#"Added Custom1"
Instead of going step by step, you can just paste this into the Advanced Editor if you'd like. (Just be sure you use whatever table name you have instead of Targets.)
I have a much simpler solution for this:
I just need to be able to create a table with a date - daily target - salesperson. based on the monthly targets
Let's say I have a table like this:
Where Month contains the date for the first day of each month. We then add a custom column "Date" using the query editor menu (Add Column > Custom Column). We paste this formula for our new column:
= List.Dates([Month], Date.Day(Date.EndOfMonth([Month])), #duration(1, 0, 0, 0))
Each row of the new column will contain a list of all dates within that row's month. Expand that column by clicking on the button on the top right corner and choosing "Expand to new rows".
Now you have a row for each day, and you can simply add another custom column, "Daily Target", that divides the monthly target by the number of days in each month:
= [Monthly Target]/Date.DaysInMonth([Date])
And your table is ready:
I have a following employee table value as below :
name | cost
john | 1000
john | -1000
john | 5000
when we add the cost column total will be 5000.
I need to print only the 3rd row in BIRT report, since the 1st and 2nd row get cancelled out each other.
I'm stuck at filtering the table for above scenario.
Couldn't you just solve this using SQL like
select name, sum(cost)
from employee
group by name
order by name
?
Or do you just want to exclude two rows if they have exactly the same cost, but with different signs? Note that this is actually something different, take for example the three rows [ john|1, john|2, john|-3 ]? In this case, a pure SQL solution can be achieved using the SQL analytic functions (at least if you are using Oracle).
Elaborate your question. Its not clear if these are columns or rows.
If These are columns:
Create a computed column in your dataset
In Expression builder of that column add/sub values using dataSetRow['col1'] and dataSetRow['col2']
Add only that computed column to your table.
If these are rows
Select rows you don't want to print
Go to properties tab
Find Visibility property and click on it
Check Hide Element option
What is the best way to store occurrences of an event in a database so you can quickly pull reports on it? ie (total number of occurrences, number of occurrences between date range).
right now I have two database tables, one which holds all individual timestamps of the event - so I can query on a date range, and one which holds a total count so I can quickly pull that number for a tally
Table 1:
Event | Total_Count
------+------------
bar | 1
foo | 3
Table 2:
Event | Timestamp
------+----------
bar | 1/1/2010
foo | 1/1/2010
foo | 1/2/2010
foo | 1/2/2010
Is there a better approach to this problem? I'm thinking of converting Table 2, to hold date tallies, it should be more efficient, since my date range queries are only done on whole dates, not a timestamp (1/1/2010 vs 1/1/2010 00:01:12)
ie:
Updated Table 2
Event | Date | Total_Count
------+----------+------------
bar | 1/1/2010 | 1
foo | 1/1/2010 | 1
foo | 1/2/2010 | 2
Perhaps theres an even smarter way to tackle this problem? any ideas?
Your approach seems good. I see table 2 more as a detail table, while table 1 as a summary table. For the most part, you would be doing inserts only to table 2, and inserts and updates on table 1.
The updated table 2 may not give you much additional benefit. However, you should consider it if aggregations by day is most important to you.
You may consider adding more attributes (columns) to the tables. For example, you could add a first_date, and last date to table 1.
I would just have the one table with the timestamp of your event(s). Then your reporting is simply setting up your where clause correctly...
Or am I missing something in your question?
Seems like you don't really have any requirements:
Changing from timestamp to just the date portion is a big deal.
You don't ever want to do a time-of-day analysis?
like what's the best time of day to do maintenance if that stops "foo" from happening.
And you're not worried about size? You say you have millions of records (like that's a lot) and then you extend every single row by an extra column. One column isn't a lot until the row count skyrockets and then you really have to think about each column.
So to get the sum of event for the last 3 days you'd rather do this
SELECT SUM(totcnt) FROM (
SELECT MAX(Total_count) as totcnt from table where date = today and event = 'Foo'
UNION ALL
SELECT MAX(Total_count) from table where date = today-1 and event = 'Foo'
UNION ALL
SELECT MAX(Total_count) from table where date = today-2 and event = 'Foo'
)
Yeah, that looks much easier than>
SELECT COUNT(*) FROM table WHERE DATE BETWEEN today-2 and today and event = 'foo'
And think about the trigger it would take to add a row... get the max for that day and event and add one... every time you insert?
Not sure what kind of server you have but I summed 1 Million rows in 285ms. So... how many millions will you have and how many times do you need to sum them and is each time for the same date range or completely random?