Filter data with start & end date in intervals (months, weeks) - dax

I am trying to build a data-analysis table (in PowerBi if that matters) that shows sum of task hours per resource (row) and date-window (column).
I.e getting a result as ...
Resource
Month 1
Month 2
AB
40h
30h
BB
20h
10h
My data however is structured in a way that I have one data point per resource/task combination without breaking down the date. I.e. the data is structured like ...
Resource
Task
Hours
Start
End
AB
XX
10h
10.10.22
01.02.23
AB
XZ
5h
01.11.22
05.11.22
So i need to sum all tasks per resource but also break them down to how many hours per month. Ideally i can also switch to weeks view in my dashboard.
How can I best achieve this?
Transform the data? Some special filter?
Any Tips or pointers to tutorials ecc. would be great. Thanks.
Best

If you can store a lot of data, you should do something like this:
calculate hours per date for every Resource-Task group (this can be done inside original table);
create a new calendar table (one column with dates) and cross-join it with distinct Resources;
add a column to newly created table where you will calculate sum of hours per this date and Resource;
use this analytical table for your purposes grouping data by necessary periods.

Related

Howe to count an event by minute in Big Query

Many years ago I knew SQL quite well but apparently it's been so long I lost my skills and knolwedge.
I have a number of tables that each track a given event with additional metadata. One piece of Metadata is a timestamp in UTC format(2021-08-11 17:27:27.916007 UTC).
Now I need to count how many times the event occurred per minute.
Col 1, Col2
EventName, Timestamp in UTC
I am trying to recall my past knowledge and also how to apply that to BQ. Any help is appreciated.
If I'm understanding well, you could transform your Timestamp into minutes and then group by it.
SELECT count(*) AS number_events,
FLOOR(UNIX_SECONDS(your_timestamp)/60) AS minute
FROM your_table
GROUP BY FLOOR(UNIX_SECONDS(your_timestamp)/60)
So it transforms your timestamps to unix_seconds, then divide by 60 to get minutes and floor() to skip decimals after the division.
If you have multiple type of events in the same table, just add the name of the event to the select and to the group by
The first step would be to group by event column.
Then the Timestamp events can be counted.
Select Col2_EventName, count(Timestamp )
group by 1
Depending on your data, some more transformation have to be done. E.g. ignore the seconds in the timestamp and hold only the full minutes, as done in the answer from Javier Montón.

Cognos 11 Crosstab - need a value that doesn't have a reference to the column values

Crosstab report works 99%.
About 20 rows, all but one are ok.
5 columns - Company Division.
The rows are things like cost, revenue, revenue 2, etc.
All the rows that work have three attributes I'm using to select them:
Fiscal Year
Period
Solution.
The problem is there is table that lists an YTD rate for each period. This table is not Division Specific; it's company wide.
All the tables are linked to the accounting period table that has fiscal year and period. So the overall query limits data to fiscal year (?pFiscalYear?) and period <= ?pPeriod?, based on prompt page results.
The source table has this:
FY_CD PD_NO ACT_CURR_RT ACT_YTD_RT
2018 1 0.36121715 0.36121715
2018 2 0.32471476 0.34255512
2018 3 0.25240906 0.31210183
2018 4 0.33154745 0.31925874
Note the YTD rate is not an average of any of the other numbers.
When I select the ACT_YTD_RT, as a row, I want the ACT_YTD_RT that matches the selected period.
What I get is the average if I set the aggregation to average or the lowest if I set it to other aggregations. So sometimes, it looks right (if I run for period 1,2,3, as the rate kept falling), and sometimes it's wrong (period 4
returns .3121 instead of .3192).
I've tried a number of different methods and can generate garbage data (totals, min, max, average) and crossjoins but can't figure out how to get the value I'm looking for.
I want YTD_RT where fiscal year =?pFiscal? and period = ?pPeriod?.
I tried a straight if then clause:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
but I get an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
If I create another query that generates the right response and try to include it, I get a crossjoin error that the query I'm referencing is trying to crossjoin several other items in the crosstab query.
A union doesn't work (different number of columns).
Not sure how a join would work since the division doesn't exist in the rate table.
I maybe could create a view in the database that did a crossjoin of the division table and the rate table, add that to the framework and then I wouldn't have a crossjoin since the solution would be in the rate "table" (really view), but that seems wrong somehow.
If I could just write a freaking parameterized query direct to the database I'd be done. But in Cognos 11 crosstabs I can't find a place for a SQL query object. And that shouldn't be necessary.
I've spent hours and hours chasing this in circles.
Anybody have any ideas?
Thanks
Paul
So the earlier problem was that this:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
Generated an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
To fix the above, I had to add a cross join of the division table and the rate table as a view in the database. Then add that to the framework. Then build the data item this way:
total (
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
)
And now the "total" provides the missing group by. And the crossjoin in the database provides the division information so the crosstab is happy.
I still think there should have been an easier way to do this, but I have a functioning hammer at the moment.

Building a matrix with columns == days of month when recordset cannot return all days of month

I'm trying to put together an attendance report for a school that tracks student attendance codes for that student for every day on the calendar month in a DynamicsCRM system being used as a managed service (that is to say, I build queries using FetchXML and cannot use SQL). The format for the report requires that a column for every day in the month be listed for the report. My student table that tracks this attendance however only contains records for days where an attendance value is recorded, and I do not have an object available that can return every day in a month for me.
I am looking for a solution other than hardcoding 31 columns and using conditionals to control the display of the last three day columns. Ideally, I'd like a conditional in my matrix column grouping that would look at the date value for the previously generated column and determine if the next date record from my resultset is sequentially the next day of that month, and if not, create the next sequential date, move to the next column and perform the check again until it is true. Is there a way I can do this, or another means to accomplish my goal that does not involve hard-coding day columns into a table or matrix? Right now, I have nothing; I can barely imagine how I think this should look.
What I did to solve the same issue has been to create a scheduled process each day to create a record and deactivate it.
I have then been able to distinguish actual records (the active ones) from these 'placeholders' (inactive ones) in my querying.

Can I generate the number of business days in a month in Visual Studio?

I have a report that takes sales data from a few tables. I want to add a field that will divide the total sales for the given month by the total number of business days in that same month. Is there a way I can calculate that in an expression? Do I need to create a new table in the database specifically for months and their number of business days? How should I go about this?
Thank you
Intuitively, I would say that you need a simple function and a table.
The table is to host the exceptions like Independence day, labor day, etc.
The function will get two parameters: Month and Year (I'm not providing any sample code since you haven't specified which language you are using).
It will then build a date as yyyy-mm-01 (meaning, first day of the month). If will then loop from 2 to 31 and:
Create a new date by adding the index of the loop to the initial date,
Check if the resulting date is still within the month,
Check if it is a working or not working day (e.g. Sunday),
Check if it is found within the table of exceptions.
If the created date passes all the above tests, you add 1 to the counter.
Though it might look complex, it is not and it will provide you the correct answer regardless of the month (e.g. Feb.) and the year (leap or not).

SSRS Matrix Bespoke Headers (Still from datasource!!)

I have to create a matrix in SSRS to detail the number uses leaving an organisation.
The columns will all represent spaces of time spanning 1 week and the rows will all represent departements in the organisation. The detail portion will be a count of people who have left that area in that week.
I have a leaving date field in the DB but nothing that flags the specific intevals I have been told to use. That means that as the matrix is, it counts each of users that have left a specific department however the date range columns is 1 day, not 1 week. Is there a way to force the column headers to respect the week intervals I want given that they are currently coming from the dataset and are not hard coded?
Firstly try to manage your data in sql itself by using Group By with date and making each group as one week period. That way you can manage to get all data in your required format
I don't know what is your columns so I am just showing a way to get the week groups from table and get the count of the people
SELECT DATEPART(wk, datevaluecolumn) weekno
, SUM(peopleleavingcolumn) totalvalue
FROM yourTable
GROUP BY DATEPART(wk, datevalue)

Resources