How to use Dense Rank for Date Field in Business Objects - sap

I am trying to filter for only latest 4 weeks of data in Business objects, In the below example I want to retrieve are filter for only data for below dates(Latest Weeks). Week Date is a field which is every Monday date of the week.
10/9/2017
10/2/2017
9/25/2017
9/18/2017
Week Date Sales
8/28/2017 100
8/28/2017 101
9/4/2017 102
9/4/2017 103
9/11/2017 104
9/11/2017 105
9/18/2017 106
9/18/2017 107
9/25/2017 108
9/25/2017 109
10/2/2017 110
10/2/2017 111
10/9/2017 112
I tried with Rank Function and spent hours finding solution but had no luck. I hope Dense Rank would help, later I can filter for 1 to 4.

You could do this in one variable and a filter on that variable, but I like to break things down to understand exactly what is happening. You can always combine variables later.
First, create a variable to represent the cutoff date...
[CutOff Date] = RelativeDate(CurrentDate(); -4; WeekPeriod)
Second, create another variable to determine if a particular week should be included...
[Last Four Weeks] = If([Week Date] > [CutOff Date]; 1; 0)
Finally, create filter on to only show the last four weeks...
[Last Four Weeks] = 1
You may need to adjust the values depending on the timing of when you are running your report, but that is the general idea.
As I mentioned earlier, you could combine [CutOff Date] and [Last Four Weeks] into one variable...
[Last Four Weeks] = If([Week Date] > RelativeDate(CurrentDate(); -4; WeekPeriod)
; 1; 0)
Noel

Related

How can I handle a Julian Date rollover in SQL?

I have a list of julian dates that I need to keep in order ex. 362, 363, 364, 365, 001, 002, 003. My query starts with getting the last julian date processed and each date after that. Right now it will max my lowest date out at 365 and I can't get the records that follow it. The same set of data also has a date field with the year attached but it doesn't seem to be helpful since those records won't be gathered until the rollover is corrected. Here is my simplified query:
select JulianDate, RecordDate
from table
where JulianField > #LowestJulianDate
and RecordDate between GetDate() and DateAdd(day, 6, GetDate())
Sample date:
JulianDate
RecordDate
362
2020-12-28
363
2020-12-29
364
2020-12-30
365
2020-12-31
001
2021-01-01
002
2021-01-02
003
2021-01-03
Desired output:
JulianDate
362
363
364
365
001
002
003
So if you'll imagine we start on day 362, our #LowestJulianDate is 362, and our record date range is today and the next 6 days, completing that list of julian dates.
How can I get the dates to go in order and resolve in a rollover?
You cannot by just using the "JulianDate" which is actually the DayOfYear value. You would need to also store the year that it refers to either separately or as part of the "JulianDate" value. For example, instead of "362" you need "2021362".
well why not sorting by year column and Julian date column ?
select JulianDate, RecordDate
from table
order by yearcolumn,JulianDate
What we are doing in the case of not having a year and wanting to sort a list on the year rollover for a 7 day rolling window is looking at the left 1 of the Julian day. If it's less than 3 roll it's rolled over. We sort into 2 baskets (old year and new year), order them, then recombine them with the new year's data being the "greatest" in the list.
We look at the left 1 because in our application, the last day of data we get may be 357 and the rollover may be 003 for example.

MS Access - SQL Query for Average of Each Day Data

I have a set of data spanning across 3 days. Based on the first column from the left, is it possible to have a query that calculates the average of the values in the third column from the left based on each day?
The end result will be two columns:
1/1/2008 | 1.605
2/1/2008 | 1.59
3/1/2008 | 1.56
I think the logic will be something like in a loop:
Based on the day in the first column, if it is the same day, count the number of rows and add up the values of the third column
Use the sum of the values of the third column and divide by the number of rows to get the Average
day + 1
But how can we implement a loop in MS Access?
Here is the set of data:
Edit:
If I want to group by the date, where the day is between yesterday's 6PM to today's 6PM?
The BETWEEN clause is to check for records that are between yesterday's 18:00:00 and today's 18:00:00. Example, for 1/1/2008, the record will start from 1/1/2008 6:00PM to 2/1/2008 6:00PM. For 2/1/2008, the record will start from 2/1/2008 6:00PM to 3/1/2008 6:00PM`. So on and so forth...
I have a code snippet that checks for this:
([In process analysis result].[Date Time]) Between Date()-1+#12/30/1899 18:0:0# And Date()+#12/30/1899 18:0:0#)
But it only groups for one day before. How can I apply for the set of data?
Edit 2:
This is the query that I have done, but it is still not correct. Any idea what is wrong?
SELECT DateValue([Date Time]) As DateValue, Avg([MFR g/10min]) AS [AvgOfMFR g/10min]
FROM [In process analysis result]
WHERE ((([Date Time])>Now()-365) AND (([Operation Grade-Load]) Like "EX*") AND (([Date Time]) Between [Date Time]-1+#12/30/1899 18:0:0# And [Date Time]+#12/30/1899 18:0:0#))
GROUP BY DateValue([Date Time]);
SELECT the AVG of the value and GROUP BY the date
Your logic looks basically correct. The where clause looks off. Start with this:
SELECT DateValue(DateAdd("h", 6, [Date Time])) As DateValue,
Avg([MFR g/10min]) AS [AvgOfMFR g/10min]
FROM [In process analysis result]
WHERE [Date Time] > DateAdd("yyyy", -1, DateAdd("h", 6, Now())) AND
[Operation Grade-Load] Like "EX*"
GROUP BY DateValue(DateAdd("h", 6, [Date Time]));
I'm not sure what the BETWEEN condition is supposed to be doing. If
you want a particular date range, just use date constants.
Edit: Date/time should be offset by 6 hours as in the above edit. And a proper 1-year-back expression should be used. Not sure if current time should be shifted 6 hours too (shown); if not, just remove the DateAdd of Now().

Tabular Query to Compare Measures Across Dates

I've got a number of rows and I want to calculate the difference per date.
So say I have the following:
[Date] [Transaction Number] [Value]
1 Jan 16 1 1000
2 Jan 16 1 980
I then want a fact that for every row will compare the value with the measure from the previous date.
So If I have a measure on SUM(Value) for the current date, I basically want SUM(CurrentDate) - SUM(PreviousDate) to see the movement.
A couple of things to note:
There will actually be a couple of comparisons: previous date, previous month end, previous year end.
I want this as a calculated measure not column so that I do not need to filter on the transaction number in the previous period.
What I've tried but it just comes up empty:
Previous Value :=CALCULATE(SUM(Table[Value])) - CALCULATE(SUM(Table[Value]), FILTER(Table, Table[Date] = PreviousDay(Table[Date])))
Unfortunately I cannot tell why your measure didn't work, but following should:
Previous Value := CALCULATE(SUM(Table[Value]) - CALCULATE(SUM(Table[Value]), PREVIOUSDAY(Table[date])))

Counting days at the place

I am working on the crystal report Xi and my problem is in my report I have to show the count of the days patient spend on one place, they can get transfer any number of times or they don't get transfer even one time. So every time they transferred from their admission to discharge I want to count of days on that place the patient spend.
PatID Admission Discharge Place TransferPlace TransferDate
121 05\06\2013 06\01\2013 102 105 05\10\2013
121 105 101 05\20\2013
121 101 108 05\25\2013
Here I just created a data the patient first transfer on 05\10\2013 from 102 to 105 that means he was at 102 since he got admitted (4 days) and in 105 he was for 10 days.
I hope it should be clear.**
Try DATEDIFF() function it will return the date difference
To get the difference between dates you use the DateDiff function. In your case you want to get the amount of days between the dates, you would use:
DateDiff(day, {Admission.Date}, {Transfer.Date})
{Admission.Date} and {Transfer.Date} are the date fields you would be using in your report.
EDIT:
So I think you can make this work using the PREVIOUS function in Crystal. Try something like:
if isNull(previous({Transfer.Date}) then
DateDiff(day, {Admission.Date}, {Transfer.Date}) else
DateDiff(day, previous({Transfer.Date}), {Transfer.Date})
You could also go the other way by using the NEXT function.

How to exclude weekends data in a whole month?

I am stuck at a point where I have to exclude the weekends tickets and need to count the rest tickets(just weekdays).
Let's suppose:
tickets dates
----------- ----------
123 04/05/2012
231 04/06/2012
111 04/07/2012
112 04/08/2012
113 04/09/2012
So, In the above table we have a data for 5 days including weekday and weekend.
I just need weekday data not the weekend in my final table like this:
tickets dates
----------- ----------
123 04/05/2012
231 04/06/2012
113 04/09/2012
Don't bother with datefirst. It can cause problems
select * from #t
where datediff(d, 0, dates)%7 < 5
EDIT:
Datefirst is different from database to database. So you need to set datefirst before using 'DatePart(dw,dates)'
of the week. That means that every time you run the script you should call that datefirst. In case you decide to put it in a function you are screwed because you can't use it inside that function. So every time you call that function you rely on people remembering that datefirst part.
My solution does not rely on the individual setting of the database.
What it does is this:
calculate the days between 0 which represent 1900-01-01(a monday) and dates.
modulus 7 of that is a daynumber between 0(monday) and 6(sunday) so less than 5 is a weekday.
You typically use the combination of set datefirst and the datepart function to filter out weekdays or weekends in a query. You haven't given much in the way of table structure so use the following as a rough guide only.
An example would be like this:
set datefirst 1; /* treat monday as first day of week */
select tickets from mytable
where datepart(dw,mydate) < 6; /* select days 1 - 5 only */
Select * From Tickets Where DatePart(dw,dates) between 2 And 6
Assuming Sunday is Day one
you can mess with that with SET DATEFIRST