Displaying SSAS measure in thousands or millions - ssas

I have an Olap cube created using Microsoft SSAS. Inside I have a many-to-many relationship between source transaction currency and required "Reporting" currency. This is all functional, however to display a dynamic currency symbol I am using the "Currency" format string default and passing in a custom LCID based on the currency selected.
The problem with using the "Currency" format is the decimal places and large numbers. I am reporting millions of pounds/dollars and my CFO wants to see these numbers reported in thousands or millions. To control this I have read about using a special format string like #,, but this won't allow the currency symbol to be shown.
I had an idea to have a special dimension which would equate to 1, 1000, 1000000 and then create a calculated measure which divides by this (obviously defaulting to 1 and not aggregatable), but I have lots of measures.
Can anybody else advise on an alternative approach?

I would just set the FORMAT_STRING via a script assignment:
FORMAT_STRING(([Dim-Currency].[Currency Code].&[USD])) = "$#,,";
FORMAT_STRING(([Dim-Currency].[Currency Code].&[Euro])) = "€#,,";

You may use the SCOPE statement here:
Scope(AddCalculatedMembers([Measures].Members));
This = case
when [Measures].CurrentMember >= 1000000
then Cstr(Cint([Measures].CurrentMember / 1000000)) + " millions"
when [Measures].CurrentMember >= 1000
then Cstr(Cint([Measures].CurrentMember / 1000)) + " thousands"
else [Measures].CurrentMember
end;
End Scope;
Where Cint return int value and Cstr helps to join int value to text. I'm not sure if it's not too much. I've never used the "Currency" type, honestly.

I'm with #GregGalloway. In our cube-script it is implemented like this:
Scope
([Dim-Currency].[Currency Code].&[EUR]);
//EUR
FORMAT_STRING(This) = '€ #,##0.00';
End Scope;
Scope
([Dim-Currency].[Currency Code].&[GBP]);
FORMAT_STRING(This) = '£ #,##0.00';
End Scope;
We render via Pyramid front-end.

Related

Extract Substring with variable start and length

I have a field from a horrible database in which every value is a string such as
Field Stage changed from "Kortec Sales Cycle/3 Proposal" to "Kortec Sales Cycle/Postponed"
Or
Field Stage changed from "Kortec Sales Cycle/5 Evaluate" to "Kortec Sales Cycle/6 Implement"
I need to make 2 calculated columns from this, named 'From' and 'To', with the two values within the quote marks or the number they start with (all 7 stages except 'Postponed' begin with a number).
It's the 'To' field I need the most. I've had a try using Instr(), InStrRev(), Left, and Mid functions, but no joy so far. I've also searched online for similar problems but haven't come across any text manipulation requirements like this.
Anyone know how I should go about breaking this down?
Closest I (think I) got was
SELECT RIGHT([OppMovs (Base)].[DETAILS], InStrRev([OppMovs (Base)].[DETAILS], 'to')-3)
FROM [OppMovs (Base)]
Split can be used to easily extract these:
s = "Field Stage changed from ""Kortec Sales Cycle/3 Proposal"" to ""Kortec Sales Cycle/Postponed""
? s
Field Stage changed from "Kortec Sales Cycle/3 Proposal" to "Kortec Sales Cycle/Postponed"
? Split(Split(s, "from """)(1), """")(0)
Kortec Sales Cycle/3 Proposal
? Split(Split(s, "to """)(1), """")(0)
Kortec Sales Cycle/Postponed
However, for use in a query, you must create small helper functions like:
Public Function GetFrom(ByVal Value As String) As String
GetFrom = Split(Split(Value, "from """)(1), """")(0)
End Function
Public Function GetTo(ByVal Value As String) As String
GetTo = Split(Split(Value, "to """)(1), """")(0)
End Function

Tableau Calculated Fields IF THEN Statement adding multiple fields

I'm exploring Consumer Expenditure microdata (individual level data) from BLS and I'm looking to create a new field for investable assets by adding a number of different fields and bucketing respondents into $250K+ and <$250K. I'm using Tableau Public.
My formula is below. Various fields are things like total value of stock holdings, retirement accounts, checking & saving accounts, etc.
If [Irax] + [Irabx] + [Liquidb] + [Liquidbx] + [Othastx] + [Othastbx] + [Stockbx] + [Stockx] >= 250000 THEN "$250K+"
ELSEIF [Irax] + [Irabx] + [Liquidb] + [Liquidbx] + [Othastx] + [Othastbx] + [Stockbx] + [Stockx] > 250000 THEN "<$250K"
END
The calculation is valid, however the result is not accurate. The formula buckets everyone into the >$250K bucket, even though there are clearly individuals that have over that amount.
What is happening here?
Define a field called investable assets =
[Irax] + [Irabx] + [Liquidb] + [Liquidbx] + [Othastx] + [Othastbx] + [Stockbx] + [Stockx]
Then define a numeric parameter called [investment threshold] defaulting to 250000
Then finally a calculated field called rich guy =
SUM([investable assets]) > [investment threshold]
Now you can use [rich guy] as desired, and tweak your parameter interactively.
There are other variations, you could use LOD calcs or sets instead. You can define an alias for [rich guy] to display "Loaded and Broke" instead of "True and False". But this is a typical approach for spotlighting.
BTW, the only thing that is especially different than your approach is the use of the function SUM()

Apex parse error when creating SQL query with sql function

I have the following function:
CREATE OR REPLACE FUNCTION calc_a(BIDoctor number) RETURN number
IS
num_a number;
BEGIN
select count(NAppoint)
into num_a
from Appointment a
where BIDoctor = a.BIDoctor;
RETURN num_a;
END calc_a;
What we want is adding a column to a report that shows us the number of appointments that doc have.
select a.BIdoctor "NUM_ALUNO",
a.NameP "Nome",
a.Address "Local",
a.Salary "salary",
a.Phone "phone",
a.NumberService "Curso",
c.BIdoctor "bi",
calc_media(a.BIdoctor) "consultas"
FROM "#OWNER#"."v_Doctor" a, "#OWNER#"."Appointment" c
WHERE a.BIdoctor = c.BIdoctor;
and we got this when we are writing the region source on apex.
But it shows a parse error, I was looking for this about 2 hours and nothing.
Apex shows me this:
PARSE ERROR ON THE FOLLOWING QUERY
This is probably because of all your double quotes, you seem to have randomly cased everything. Double quotes indicate that you're using quoted identifiers, i.e. the object/column must be created with that exact name - "Hi" is not the same as "hi". Judging by your function get rid of all the double quotes - you don't seem to need them.
More generally don't use quoted identifiers. Ever. They cause far more trouble then they're worth. You'll know when you want to use them in the future, if it ever becomes necessary.
There are a few more problems with your SELECT statement.
You're using implicit joins. Explicit joins were added in SQL-92; it's time to start using them - for your future career where you might interact with other RDBMS if nothing else.
There's absolutely no need for your function; you can use the analytic function, COUNT() instead.
Your aliases are a bit wonky - why does a refer to doctors and c to appointments?
Putting all of this together you get:
select d.bidoctor as num_aluno
, d.namep as nome
, d.address as local
, d.salary as salary
, d.phone as phone
, d.numberservice as curso
, a.bidoctor as bi
, count(nappoint) over (partition by a.bidoctor) as consultas
from #owner#.v_doctor a
join #owner#.appointment c
on d.bidoctor = a.bidoctor;
I'm guessing at what the primary keys of APPOINTMENT and V_DOCTOR are but I'm hoping they're NAPPOINT and BIDOCTOR respectively.
Incidentally, your function will never have returned the correct result because you haven't limited the scope of the parameter in your query; you would have just counted the number of records in APPOINTMENT. When you're naming parameters the same as columns in a table you have to explicitly limit the scope to the parameter in any queries you write, for instance:
select count(nappoint) into num_a
from appointment a
where calc_a.bidoctor = a.bidoctor; -- HERE

Crystal Reports 8.5 showing multi-values from parameters on report footer

In Crystal Reports 8.5 when I have setup a parameter for multi-value the user enters 90654-90658A. Normally I would use Join() but being that this is not just text but numeric I have tried a few things but with no results.
Local NumberVar i;
Local NumberVar j;
Local StringVar param_values;
if 0 in {?CPT} then
"CPT #s: All CPTs"
else
(
for i := 1 to UBound ({?CPT}) do
for j := Minimum ({?CPT}[ i ]) to Maximum ({?CPT}[ i ]) do
param_values := param_values + "," + CStr (j, "#");
"CPT #s: " + Mid (param_values, 2)
)
This works fine for 90654-90658 but when the user selects 90654-90658A it fails.
Also the selection criteria will not pass to SQL in the query sent to SQL with the correct where clause. Meaning there is not indication that I am even asking for a where. It should show in the select for sql a where table.data >= '90654' and table.data <= '90658A'
I am lost as to where I am going wrong with this. Any help would be great this is my first time seeking an answer on this site but I have not received any help on this request.
Thanks
I tried a similar query with the Xtreme.mdb database, referencing the Customer table. I created a string, range parameter that accepted multiple values (i.e. multiple ranges).
When I supplied it with two ranges, the follow query was generated:
SELECT `Customer`.`Postal Code`
FROM `Customer` `Customer`
WHERE (
(`Customer`.`Postal Code`>='04000' AND `Customer`.`Postal Code`<='04999') OR
(`Customer`.`Postal Code`>='55000' AND `Customer`.`Postal Code`<='55999')
)
As you can see, Crystal Reports will build the necessary BETWEEN or >= <= statements.
In you situation, try:
( "0" IN {?CPT} OR {TABLE.FIELD} IN {?CPT} )
You could adapt your formula field to display the values of the parameter, if you want.
I do appreciate everyones input but I was able to work through the problem. For the record selection I put in the following. {TABLE.FIELD} in CStr({#MinCPT}) to CStr({#MaxCPT}). This pulled the range after I created two formulas. One MinCPT and the other MaxCPT. Here is the formula. Left (ToText (Minimum ({?CPT})),2 ) & Mid (ToText (Minimum ({?CPT})),4 ,3 ) and the same for Max. The report works fine now.
Thanks Again.

MDX CurrentMember with SSAS 2008 doesn't work as stated by MSDN

First of all I use the SQL Management Studio for this query (no Excel 2007 that seems to have problems):
WITH
SET [Project period dates] AS
{
StrToMember("[Time].[Date].&[" + [Project].[ParentProject].CURRENTMEMBER.PROPERTIES("Project Start Iso") + "]"):
StrToMember("[Time].[Date].&[" + [Project].[ParentProject].CURRENTMEMBER.PROPERTIES("Project End Iso") + "]")
}
MEMBER [Measures].[Test] AS ([Project period dates].COUNT)
SELECT
{
[Measures].[Test]
}
on 0,
NONEMPTY ([Project].[ParentProject].MEMBERS)
DIMENSION PROPERTIES [Project].[ParentProject].[Project Duration], [Project].[ParentProject].[Project Start Iso], [Project].[ParentProject].[Project End Iso]
on 1
FROM
[MyCube]
WHERE
(
[Orgunit].[Orgunit].&[448]
)
This query delivers a list of projects with its three properties and a calculated member that is based upon my calculated set. The properties show the right values, but the calculated member shows always the same: the result of the very first project it should be calculated for.
I don't really understand why, because MSDN says:
The current member changes on a hierarchy used on an axis in a query.
Therefore, the current member on other hierarchies on the same
dimension that are not used on an axis can also change; this behavior
is called 'auto-exists'.
They give examples with calculated members, but I think that should also work with calculated sets, I have read that query-based calculated sets are dynamic by nature. Maybe somebody can tell me if I understood that wrong or what else is my problem here.
The named set are only computed once within a query. That is why your calculated member always return the same value.
You just have to remove the named set from your query:
MEMBER [Measures].[Test] AS {
StrToMember("[Time].[Date].&[" + [Project].[ParentProject].CURRENTMEMBER.PROPERTIES("Project Start Iso") + "]"):
StrToMember("[Time].[Date].&[" + [Project].[ParentProject].CURRENTMEMBER.PROPERTIES("Project End Iso") + "]")
}.COUNT