DAX Query - COUNTROWS statement using EARLIER - powerpivot

I need to compare :
Contact Employee ID to EARLIER Contact Employee ID (if they equal)
and difference between Opendate_Int and EARLIER Opendate_Int (if less than or equal to six then count the row).
My query (Data is the name of the table in Power Pivot):
=COUNTROWS(FILTER('Data', EARLIER([Contact Employee ID]) = [Contact Employee ID] && EARLIER(Data[OpenDate_Int],[OpenDate_Int]-[OpenDate_Int]) <=6))+1
I am getting an error:
"The second argument of function EARLIER must be an integer greater than zero."
Can you tell me where I am going wrong? Example (tables):

Your error is thrown due to this part of your measure:
EARLIER(Data[OpenDate_Int],[OpenDate_Int]-[OpenDate_Int])
The EARLIER function in dax takes two arguments. The first argument is mandatory and should be a column. The second argument is optional and should (if provided) be an integer greater than 0.
In your statement the second argument is this:
[OpenDate_Int]-[OpenDate_Int]
which will always resolve to 0, because you are basically substracting a number from itself.
I assume that what you want to achieve is this:
=
COUNTROWS(
FILTER(
'Data',
EARLIER([Contact Employee ID]) = [Contact Employee ID]
&& EARLIER([OpenDate_Int])-[OpenDate_Int]) <=6
)
)+1
This part of the statement:
&& EARLIER([OpenDate_Int])-[OpenDate_Int]) <=6
will check whether the [OpenDate_Int] subtracted from the EARLIER [OpenDate_Int] is less than or equal to 6.

Related

How to create calculated field in Tableau to return count of instances of value

I'm trying to create a calculated field in Tableau to display a percentage. I have a couple fields that I'm working with: "Record ID" and "Was contact made?" (Yes/No). I want to show the percentage of Record IDs that show up 4 or more times as "Yes" under the field "Was contact made?"
First, I created a calculated field to turn "Was contact made?" "Yes" answers into a 1:
Contact made =1:
CASE [Was contact made?] WHEN "Yes" THEN 1 END
This calculation to get the percentage:
str(countd(if [Contact made = 1] >=4 then [Record ID] end)
/
countd([Record ID]))+"%"
When I put the previous calculation in text, it gives "0%", which is not accurate
You could make an LOD calc called Heavily Contacted? defined as
{ FIXED [Record ID] : SUM(INT([Was contact made?] = "Yes")) >= 4 }
This takes advantage of the fact that the type conversion function INT() converts TRUE values to 1 and FALSE values to 0.
One way to get the value you want could then be
COUNTD(if [Heavily Contacted?]) then [Record ID] end) / COUNTD([Record ID])
That calculation returns a numeric value. I'd just set the default number format for the field to display it as a percentage instead of converting it to a string. (Right click on the field name in the data pane, and look under Default Properties.
With a little more info about your worksheet and problem, you could likely define a field that got the same results without resorting to using COUNTD - as COUNTD can be expensive on large datasets.

MDX Calculated member SUM with OR

I inherited some mdx code which uses calculated members and the sum function. I need to make a new member using SUM but and OR (union?) set. I have tried various syntaxes but they all error.
I have code as below:
-- uses this date filter
set [as_of_month] as {strtomember("[Date].[Year - Month].[Month].&[" + cstr(format(cdate("Jul 2019"),"yyyy-MM")) + "-01T00:00:00]")}
-- member 1
member [SIONLY_MTH] as sum([as_of_month] * [Incident Details].[Is SI].[Is SI], [Measures].[Environment Impact Count])
-- member 2
member [MajorNC_Month] as sum([as_of_month] *
[Impact].[Impact].&[3] *
[Non Compliance].[Non Compliance Type].&[Major non-compliance],
[Measures].[Non Compliance Count]) + 0
-- I need a new member which is an OR of the previous 2, ie, count of
-- SI_ONLYMONTH or [MajorNC_Month] filtered by [as_of_month]
member [LegalSI_EnvSI_Month] as SUM([as_of_month] * {[Incident Details].[Is SI].[Is SI] , [Non Compliance].[Non Compliance Type].&[Major non-compliance]}
, [Measures].[Environment Impact Count]) + 0
The set inside the last sum function doesnt work, it returns #Error.
Does anyone know how to use a unioned set as the argument to the SUM function in mdx?
Thanks
Your problem basicly deals with the concepts of dimensionality and hierarchility
Try this
sum(
{
([as_of_month] * [Incident Details].[Is SI].[Is SI][Impact].[Impact].defaultmember[Non Compliance].[Non Compliance Type].defaultmember),
([as_of_month] * [Incident Details].[Is SI].defaultmember*[Impact].[Impact].&[3]*[Non Compliance].[Non Compliance Type].&[Major non-compliance])
}
,
[Measures].[Environment Impact Count])
Edit: Includes explanation on how and why the above query works.
In your problem you have two sets that have diffrent hierarchies in them. So you have to balance them. Lets take a look at your first set
sum([as_of_month] * [Incident Details].[Is SI].[Is SI],
[Measures].[Environment Impact Count])
This doesnt explicitly include "[Impact].[Impact]" however before executing SSAS takes the liberty to include [Impact].[Impact].defaultmember in the query. Based on this fact I balanced both of your sets by expicitly including the default members of attribute hierarchies that were orignally not part of your Set.
Next I encapsulaed them in "()" to indicate that they are a tuple of a larger Set.Then both these tuples are encapsulated in "{}" like this "{(tuple1),(tuple2)}"

SAP BO - how to get 1/0 distinct values per week in each row

the problem I am trying to solve is having a SAP Business Objects query calculate a variable for me because calculating it in a large excel file crashes the process.
I am having a bunch of columns with daily/weekly data. I would like to get a "1" for the first instance of Name/Person/Certain Identificator within a single week and "0" for all the rest.
So for example if item "Glass" was sold 5 times in week 4 in this variable/column first sale will get "1" and next 4 sales will get "0". This will allow me to have the number of distinct items being sold in a particular week.
I am aware there are Count and Count distinct functions in Business Objects, however I would prefer to have this 1/0 system for the entire raw table of data because I am using it as a source for a whole dashboard and there are lots of metrics where distinct will be part/slicer for.
The way I doing it previously is with excel formula: =IF(SUMPRODUCT(($A$2:$A5000=$A2)*($G$2:$G5000=$G2))>1,0,1)
This does the trick and gives a "1" for the first instance of value in column G appearing in certain value range in column A ( column A is the week ) and gives "0" when the same value reappears for the same week value in column A. It will give "1" again when the week value change.
Since it is comparing 2 cells in each row for the entire columns of data as the data gets bigger this tends to crash.
I was so far unable to emulate this in Business Objects and I think I exhausted my abilities and googling.
Could anyone share their two cents on this please?
Assuming you have an object in the query that uniquely identifies a row, you can do this in a couple of simple steps.
Let's assume your query contains the following objects:
Sale ID
Name
Person
Sale Date
Week #
Price
etc.
You want to show a 1 for the first occurrence of each Name/Week #.
Step 1: Create a variable with the following definition. Let's call it [FirstOne]
=Min([Sale ID]) In ([Name];[Week #])
Step 2: In the report block, add a column with the following formula:
=If [FirstOne] = [Sale ID] Then 1 Else 0
This should produce a 1 in the row that represents the first occurrence of Name within a Week #. If you then wanted to show a 1 one the first occurrence of Name/Person/Week #, you could just modify the [FirstOne] variable accordingly:
=Min([Sale ID]) In ([Name];[Person];[Week #])
I think you want logic around row_number():
select t.*,
(case when 1 = row_number() over (partition by name, person, week, identifier
order by ??
)
then 1 else 0
end) as new_indicator
from t;
Note the ??. SQL tables represent unordered sets. There is no "first" row in a table or group of rows, unless a column specifies that ordering. The ?? is for such a column (perhaps a date/time column, perhaps an id).
If you only want one row to be marked, you can put anything there, such as order by (select null) or order by week.

How do I reuse a created member throughout an MDX statement?

I have a bunch of calculated members that I need to create which are referenced off a single date.
Rather than repeating the MDX that gets the date member for which the measure will be based off, is there a way to create the date member at the start, and then reference it throughout so that I don't have to repeat the MDX multiple times? I was thinking something like the below however it returns a NULL:
WITH MEMBER [Date].[Retail].[Closing Date] AS
IIF (
[Date].[Retail].CurrentMember.Level.Name = 'Date',
[Date].[Retail].CurrentMember.PrevMember,
[Date].[Retail].CurrentMember
)
MEMBER [Measures].[Closing New] AS
(
[Date].[Retail].[Closing Date],
[Measures].[On Hand Quantity]
)
SELECT
[Date].[Retail].[Date].Members ON ROWS,
{
[Measures].[On Hand Quantity],
[Measures].[Closing New]
} ON COLUMNS
FROM
Retail
WHERE
[Date].[Retail Year].&[2017]
As above, I want to use the Closing Date member multiple times for various calculations.
To investigate why it is returning null try something like the following to see if it is as you expect:
WITH
MEMBER [Measures].[nm] AS
[Date].[Retail].CurrentMember.Level.Name
SELECT
{
[Measures].[On Hand Quantity],
[Measures].[nm]
} ON 0,
[Date].[Retail].[Date].Members ON 1
FROM Retail
WHERE [Date].[Retail Year].&[2017];
(I also switched the declaration order inside the SELECT clause as it is standard to declare columns, as it is axis 0, first followed by rows)
Why yes, there is!
the pattern I follow here is to create a set of one member then reference the first item of that set.
with set currentDate as
[Date].[Retail].[Date].&[20160725]
then reference it in the remainder of your query as
currentDate.item(0)

Using SQL aggregate results as condition in SELECT clause

I am trying to resolve the issue with SQL query where I have next columns:
ITEM NUMBER and CROSS_REFFERENCE. ITEM NUMBER can have multiple values of CROSS_REFFERENCE and what I need is to count them which i can do by grouping by and count by expression. But another thing that i need is statement that say, if the ITEM NUMBER has more than one CROSS_REFFERENCE than return MULTI, otherwise return the single value of CROSS_REFFERENCE that is tied to ITEM NUMBER.
I tried to usex this expression as new coulmn:
MFG: IIf(Count([CROSS_REFERENCE])>1,"MULTI",[CROSS_REFERENCE])
But when my results returns i dont get unique list of ITEM NUMBER with ether MULTI, or value for CROSS_REFERENCE.
Any idea what am i doing wrong?
SELECT
tbl_MFG_XREF.[ITEM NUMBER],
tbl_MFG_XREF.CROSS_REFERENCE,
Count(tbl_MFG_XREF.CROSS_REFERENCE) AS CountOfCROSS_REFERENCE,
IIf(Count([CROSS_REFERENCE])>1,"MULTI",[CROSS_REFERENCE]) AS MFG
FROM
tbl_MFG_XREF
GROUP BY
tbl_MFG_XREF.[ITEM NUMBER], tbl_MFG_XREF.CROSS_REFERENCE;
You need a base query:
SELECT
[ITEM NUMBER],
Count(CROSS_REFERENCE) AS CountOfCROSS_REFERENCE,
First(CROSS_REFERENCE) AS FirstCROSS_REFERENCE
FROM
tbl_MFG_XREF
GROUP BY
tbl_MFG_XREF.[ITEM NUMBER];
Instead of First you can also use Last or Min or Max. FirstCROSS_REFERENCE will only be used if there is only one CROSS_REFERENCE for an item.
Save this query as e.g. qryItemCountCrossref
And a second query that uses it as input, e.g.
SELECT
[ITEM NUMBER],
CountOfCROSS_REFERENCE,
IIf(CountOfCROSS_REFERENCE > 1, "MULTI", FirstCROSS_REFERENCE) AS MFG
FROM qryItemCountCrossref