Tableau: How do I convert date to month-week #? - tableau-api

I have a date column. For example, the date is 8/2/2022, I'm hoping to see that this will convert to Aug Week 1; and if let's say the date is 7/15/2022, then the result should say July Week 3.
Please help, thanks!

You need to use LOD to do so, as default, you can only do week numbers by year in tableau, you need to create two calculated field to do so:
1.Create a [Min-Week] calculation field as shown below:
{ FIXED MONTH([Date]):MIN(DATEPART('week',[Date]))}
Note the calculation above for [Min-Week] assumes that there is at least one record for the first week of each month. If your data does not allow you to rely on that assumption, you could instead use DATEPART('week', DATETRUNC('month', [Date]))
2.Create a [Week-By-Mth] calculation field as shown below :
CASE DATEPART('week',[Date]) WHEN [Min-Week] THEN "Week 1" WHEN [Min-Week]+1 THEN "Week 2" WHEN [Min-Week]+2 THEN "Week 3" WHEN [Min-Week]+3 THEN "Week 4" WHEN [Min-Week]+4 THEN "Week 5" WHEN [Min-Week]+5 THEN "Week 6" END
EDIT good answer - here's just a shorter equivalent expression for [Week-By-Mth]
"Week " + STR(DATEPART('week, [Date]) - [Min-Week] + 1)
If you prefer an integer to a string, you could simplify further by getting rid of the Week prefix and the STR() call.
The [Week-By-Mth] calculation field should be what you need.

Related

Tableau - Filter based on parameter

I have a dataset of dates. It has just one column CreatedOnDate and its values are in datetime as shown below.
This dataset has 6 months of values as shown. I have a parameter called Report Type which has possible values Monthly, Weekly, Daily (Screenshot below)
I have created a calculated field (called Created On Date) which converts the date based on Report Type selected. The formula is shown below
CASE [Report Type]
WHEN "Monthly" THEN DATENAME('month', [CreatedOnDate])
WHEN "Weekly" THEN "Week " + STR(DATEPART('week',[CreatedOnDate]))
WHEN "Daily" THEN STR(MONTH([CreatedOnDate])) + "/" + STR(DAY([CreatedOnDate])) + "/" + STR(YEAR([CreatedOnDate]))
END
This works perfectly. The result of the calculated field is shown below.
I now need to incorporate the following logic
IFF Report Type = "Daily" Display only the last 30 days in the dataset
Other cases Show all values
How do I achieve this?
woodhead92, I'd suggest using so called Level of Detail expressions that were introduced in Tableau v8. First create a calculated field that will calculate the most recent (=MAX) date available:
{FIXED : MAX(CreatedOnDate) }
Let's call this MaxDate LOD. Then adding a new calculated field Show/Hide:
IF [Report Type] = "Daily" AND
([CreatedOnDate] >= DATEADD('day', -30, [MaxDate LOD]) THEN 'Show'
ELSEIF [Report Type] = "Weekly" OR [Report Type] = "Monthly" THEN 'Show'
ELSE 'Hide'
END
Add this filter and select 'Show' value only. I am assuming that you want to see all dates when Weekly/Monthly date granularity is selected - if that's not the case, simply add more ELSEIF conditions.
The formula above could be simplified, but I wanted to make it as verbose as possible so that it helps you understand how Level of Detail expressions work.
One thing to keep in mind - FIXED LOD calculation overwrites filters, so if you have a date-range filter available, you will have to make sure it's added to context. More details on filter context are available here in this a bit out-dated, but still excellent blog post.
Create a calculated field for your condition and then place it on the filter shelf to include only rows that evaluate to true.
[Report Date] <> "Daily" or
datediff('day', [CreatedOnDate], { max[CreatedOnDate] } < 30
The Curley braces are significant, an LOD calculation

Qlikview Automate past 12 months selection

I have a combo chart which shows the average days it took for a person to pay their bill.
The Dimension of the Chart is = [Pay Month Year last 12 months]
There are no Dimension limits
There is 1 expression which is called Average and its definition is:
avg({< InvoicefromSqlType = {'Invoices'},[Is Invoice Paid] = {'Y'},[Is Positive Amount] = {'Y'},[Is Paid last 12 months] = {'Y'},DueGroups=,[Pay Month Year last 12 months]=>}[Days to Pay])`
Its is sorted by expression, which is [Pay Month Year last 12 months]
Now the above fields are built up like this:
[Pay Month Year last 12 months]
If([Pay Date] >= '$(vPeriodS12)',[Pay Month year]) as [Pay Month Year last 12 months],
PayLoadOrder:
Load * Inline [Pay Month Year last 12 months
May-2014
Jun-2014
Jul-2014
Aug-2014
Sep-2014
Oct-2014
Nov-2014
Dec-2014
Jan-2015
Feb-2015
Mar-2015
Apr-2015
May-2015
];
Now what is happening is every month when it reaches the end, the next month is needing to be manually added and the first month removed (e.g. in the above I would delete the line May-2014 and at the end add the line Jun-2015)
Also if there are months defined which there is no data for yet i.e. you have Jun-2015 hard coded and the current month this May-2015 then Jun-2015 will show data from 2014 and the order of the months will get mixed up.
What I want to do is completely remove the need to hard code the months above and have this done its self.
If there are any more information you need let me know
Instead of using a "sort order" table that you may have to manually update, it may be worth doing the following:
Create a new field derived from [Pay Date] that returns a month and year that you can sort. For example:
dual(date(makedate(year([Pay Date]),num(month([Pay Date]))),'MMM-yyyy'),
year([Pay Date]) * 100 + num(month([Pay Date]))) as PayMonthYear
Here, the dual function allows you to associate a different representation of a field value to its underlying value. For example, here we set the underlying data to be the year of [Pay Date] added to the month, but state that it should be displayed as MMM-yyyy. For example, internally, QV still sees the value 201502, but displays it as Feb-2015. This means you can sort it correctly based on its underlying value.
Using dual is a big topic, please consult the built-in help for QV for more information.
Change your chart dimension from [Pay Month Year last 12 months] to use PayMonthYear and set the sort to ascending. This would then mean that your months would be sorted correctly, even if a new month was added.
Remove table PayLoadOrder from your script.
Alternative Method
An alternative would be to use a calendar table which joins on your Pay Date field. This would achieve the same thing, however, you could also integrate your "year to date" indicator into the calendar as well and remove it from your main table. An example I quickly threw together is shown below:
MinMax:
LOAD
Max([Pay Date]) AS MaxDate,
Min([Pay Date]) AS MinDate
RESIDENT MyData;
LET varMinDate = Num(Peek('MinDate',0,'MinMax')); // 0 is first record
LET varMaxDate = Num(Peek('MaxDate',-1,'MinMax')); // -1 is last record
LET varToday = Num(Today());
MasterCalendar:
LOAD
monthstart([Pay Date]) >= monthstart(AddMonths(Today(),-12)) as PaidInLast12MonthsFlag,
dual(date(makedate(year([Pay Date]),num(month([Pay Date]))),'MMM-yyyy'),year([Pay Date]) * 100 + num(month([Pay Date]))) as PayMonthYear
[Pay Date];
LOAD
date($(varMinDate) + RecNo() - 1,'DD/MM/YYYY') as [Pay Date]
AUTOGENERATE num($(varMaxDate)) - num($(varMinDate)) + 1;
DROP TABLE MinMax;
So, in the above, the field PaidInLast12MonthsFlag is equal to -1 if the value of the [Pay Date] field occurs in the last 12 months, 0 otherwise. You could use this in your set analysis expression as a filter. Furthermore, you can use PayMonthYear as your chart dimension.

crystal reports month date range for earnings

My client has a report that accepts a date range to get a report showing projected revenue. So, a user would enter a date range of '1/1/2015 to 1/31/2015' and the report should return data only in the range '1/1/2015 to 1/31/2015 grouped by week. I am instead for the week of 12/29/2014 (which 1/1/2015 fall into) and 2/1/2015 (which 1/31/2015 falls into). The report is intended to group by week, but I do not want days on the report that are earlier than the start date parameter or later than the end date parameter.
The sql statement for this report is:
SELECT job.job, job.status, job.customer_po, job.part_number, job.unit_price,
job.price_uofm, delivery.promiseddate, delivery.remaining_quantity, job.build_to_stock, job.description, job.make_quantity, job.pick_quantity, job.shipped_quantity, job.lead_days
FROM dbo.delivery as delivery RIGHT OUTER JOIN db.job as job on delivery.job = job.job
WHERE job.build_to_stock = 0 AND (job.status = 'active' OR job.status = 'hold' OR job.status = 'pending')
The date range is from this code and parameters:
Max – Maximum(?Date Range)
Min – Minimun(?Date Range)
Date Range - "From " & {#Min} & " to " & {#Max}
This is the group expression
Group 2 Name - GroupName ({#Adj Date 2}, "weekly") & " thru " & cdate(GroupName ({#Adj Date 2}, "weekly"))+6
This is the select expression
{#Date} = {?Date Range} and
not {Job.Build_To_Stock} and
{Job.Status} in ["Active", "Hold", "Pending"]
Do you know how I can prevent the "overflow" of dates outside of date range?
Thx
As long as you have date filtering in your record selection formula there will not be any "overflow" outside of that range. If you've got {Record.Date} in Minimum({?DateRange}) to Maximum({?DateRange}), which it sounds like you do, then your report will not contain any records outside of the parameter regardless of how you group them.
Your problem might stem from over-complicating or misinterpreting the grouping. All you need to do is group by {Record.Date} and select "Group by week" in the grouping options... you don't need any complicated formulas to break it out by week. But be aware that the way weeks are referred to is by their starting date. For example, if you had a record with a date of Feb. 19, 2015, that record would fall into the group labeled "Feb. 15, 2015" even if your {?DateRange} parameter was Feb. 18 - Feb. 15.

Comparing Dates in If Statement

I am trying to compare dates in an expression. If the Closed_Date matches today's date (I am using Today()), then it would output 1 in the box, otherwise output 0. So far I have this but it doesn't seem to work:
=IIF(Fields!Closed_Date = Mid(Today(),1,9), "1", "0")
The reason I am using Mid is to just get the month, day, and year. I don't want the time included. Is there a way you can compare dates using this or another method?
Today() actually returns today's date at midnight, so to compare your date to today you'll need to strip the time from Closed_Date instead. I'd recommend the DateValue function, since it returns date information with time set to midnight which makes for an easy comparison:
=IIF(DateValue(Fields!Closed_Date.Value) = Today(), "1", "0")
Try something like this:
=IIF(
Format(CDate(Fields!Closed_Date), "MM/dd/yyyy") = Today()
, "1", "0"
)
OR
=IIF(
FormatDateTime(Fields!Closed_Date, DateFormat.ShortDate) = Today()
, "1", "0"
)
Avoid using string functions like Mid with the dates. There are lot of date related functions available in SSRS.

Check if the difference between dates is exactly 'n' months in expression SSRS

In my quarterly report Im trying to validate the two parameters StartDate and EndDate.
I first check if the difference between the dates is 2 months:
Switch(DateDiff(
DateInterval.Month, Parameters!StartDate.Value, Parameters!EndDate.Value) <> 2,
"Error message")
Then I try to add whether the StartDate is the first day of month AND EndDate is last day of month:
And (Day(Parameters!StartDate.Value) <> 1
And Day(DATEADD(DateInterval.Day,1,Parameters!EndDate.Value)))
So the whole expression looks like this:
Switch(DateDiff(DateInterval.Month, Parameters!StartDate.Value, Parameters!EndDate.Value) <> 2
And
Parameters!IsQuarterly.Value = true
And
Day(Parameters!StartDate.Value) <> 1
And
Day(DATEADD(DateInterval.Day,1,Parameters!EndDate.Value))<>1),
"Error: Quarterly report must include 3 months")
But It works wrong when the difference between dates is still 2 months, but StartDate and EndDate are not first and last day of the whole period.
I'd appreciate any help :)
I would say just change the implementation Add another two Parameter With Quarter and Year
Quarter like Q1,Q2,Q3 & Q4 with Value 1,2,3 & 4 respectively and year 2012,2013,2014 & so on
Now based on the parameter selected Qtr & Year set Default value of start & End Date
=DateSerial(Parameters!Year.Value), (3*Parameters!Qtr.Value)-2, 1) --First day of Quarter
=DateAdd("d",-1,DateAdd("q",1,Parameters!Year.Value, (3*Parameters!Qtr.Value)-2, 1))) --Last day of quarter
Doing this no need to do any validation bcz its always get the correct Date Difference.
Other Reference
First day of current quarter
=DateSerial(Year(Now()), (3*DatePart("q",Now()))-2, 1)
Last day of current quarter
=DateAdd("d",-1,DateAdd("q",1,DateSerial(Year(Now()), (3*DatePart("q",Now()))-2, 1)))