How to code a where clause into a calculated member? - ssas

The first query works as I needed. But when I tried to rewrite in terms of a calculated member to put it in my cube, It crashed.
select non empty [Measures].[Demanda Real] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda
where [SkSubmercadoUsuario]
First MDX query results
This is my failed try:
with member [Measures].[Demanda Real Dos]
as
([Measures].[Demanda Real], [SkSubmercadoUsuario])
select [Measures].[Demanda Real Dos] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda
What I need is slice my cube by [SkSubmercadoUsuario], but it cannot be by a where clause. I need to create a measure that slices the measure by this Named Set [SkSubmercadoUsuario]

May be you need to do something like this
with member [Measures].[Demanda Real Dos]
as
SUM({[Sk Submercado Usuario].&[52], [Sk Submercado Usuario].&[622]},
[Measures].[Demanda Real] )
select [Measures].[Demanda Real Dos] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda

I'm not sure to understand what you're trying to do.
Do you just want to create a second measure [Measures].[Demanda Real] renamed as [Measures].[Demanda Real Dos] in your query or do you want to create your measure in the "calculation script part" of your cube ?
In the first case, I think you don't need to move the condition part. Try this :
with member [Measures].[Demanda Real Dos]
as
([Measures].[Demanda Real])
select [Measures].[Demanda Real Dos] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda
where [SkSubmercadoUsuario]

Related

Problem with using SUBSTRING and CHARINDEX

I have a column (RCV1.ECCValue) in a table which 99% of the time has a constant string format- example being:
T0-11.86-273
the middle part of the two hyphens is a percentage. I'm using the below sql to obtain this figure which is working fine and returns 11.86 on the above example. when the data in that table is in above format
'Percentage' = round(SUBSTRING(RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1, CHARINDEX('-',RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1) -CHARINDEX('-',RCV1.ECCValue)-1),2) ,
However...this table is updated from an external source and very occasionally the separators differ, for example:
T0-11.86_273
when this occurs I get the error:
Invalid length parameter passed to the LEFT or SUBSTRING function.
I'm very new to SQL and have got myself out of many challenges but this one has got me stuck. Any help would be mostly appreciated. Is there a better way to extract this percentage value?
Replace '_' with '-' to string in CHARINDEX while specifying length to the substring
'Percentage' = round(SUBSTRING(RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1, CHARINDEX('-',replace(RCV1.ECCValue,'_','-'),CHARINDEX('-',RCV1.ECCValue)+1) -CHARINDEX('-',RCV1.ECCValue)-1),2) ,
If you can guarantee the structure of these strings, you can try parsename
select round(parsename(translate(replace('T0-11.86_273','.',''),'-_','..'),2), 2)/100
Breakdown of steps
Replace . character in the percentage value with empty string using replace.
Replace - or _, whichever is present, with . using translate.
Parse the second element using parsename.
Round it up to 2 digits, which will also
automatically cast it to the desired numeric type.
Divide by 100
to restore the number as percentage.
Documentation & Gotchas
Use NULLIF to null out such values
round(
SUBSTRING(
RCV1.ECCValue,
NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) + 1,
NULLIF(CHARINDEX('-',
RCV1.ECCValue,
NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) + 1
), 0)
- NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) - 1
),
2)
I strongly recommend that you place the repeated values in CROSS APPLY (VALUES to avoid having to repeat yourself. And do use whitespace, it's free.

Mdx, greater than works like String and not Numeric (Saiku)

I am using Saiku and trying to filter by mdx, using the symbol '> (greater than)', in the default Sales cube. The problem is that's it filtering like String and not Numeric. The values that I want for the query below is [51,52], but the server olap response is [6,7,8,9,51,52]. Any idea how can I filter that?
Here's the query:
WITH
SET [~ROWS] AS
{
FILTER([Time].[Weekly].[Week].Members, [Time].[Weekly]. [Week].CurrentMember.Properties("Caption") > '50')
}
SELECT
NON EMPTY {[Measures].[Unit Sales]} ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [Sales]
The response is to use 'Cint', like bellow:
WITH
SET [~ROWS] AS
{
FILTER([Time].[Weekly].[Week].Members, Cint([Time].[Weekly].[Week].CurrentMember.Properties("Caption")) > 50)
}
SELECT
NON EMPTY {[Measures].[Unit Sales]} ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [Sales]
I think there may be alternative approaches. With experimenting as some may be more efficient.
WITH MEMBER Measures.ValueColumn as [Date].[Calendar].[July 1, 2001].MemberValue
MEMBER Measures.KeyColumn as [Date].[Calendar].[July 1, 2001].Member_Key
MEMBER Measures.NameColumn as [Date].[Calendar].[July 1, 2001].Member_Name
SELECT {Measures.ValueColumn, Measures.KeyColumn, Measures.NameColumn} ON 0
from [Adventure Works]

Postresql select the first three numbers including zeros

I did not expect this to be a problem, but I'm struggling to return the first 3 numbers, including the 0's before them. In the below examples, I show a few things I've tried. I want it to return '001'. It either returns '118' or an error. It seems like every solution wants to convert them to a text, which will drop the 0's.
SELECT lpad(00118458582::text, 3, '0')
returns 118
SELECT lpad(00118458582, 3, '0')
ERROR: function lpad(integer, integer, unknown) does not exist
SELECT left(00118458582::text, 3)
returns 118
SELECT left(00118458582, 3)
ERROR: function left(integer, integer) does not exist
SELECT substring(00118458582::text, 1, 3)
returns 118
Can I get any help please? Thanks!
Your problem starts before you try to get the first 3 digits, namely that you're considering 00118458582 to be a valid INTEGER (or whatever numeric type). I mean, it's not invalid, but what happens when you run SELECT 00118458582::INTEGER? You get 118458582. Because leading zeros in those types are senseless. So you'll never have a situation as in your examples (outside of a hardcoded number with leading zeros in your query window) in your tables, because those zeros wouldn't be stored in your number-based data type fields.
So the only way to get that sort of situation is when they're string-based: SELECT '00118458582'::TEXT returns 00118458582. And at that point you can run your preferred function to get the first 3 characters, e.g. SELECT LEFT('00118458582', 3) which returns 001. But if you're planning on casting that to INTEGER or something, forget about leading zeros.
SELECT substring(00118458582::text, 1, 3)
returns 118 because it is a number 118458582 (the leading zeros are automatically dropped), that is converted to text '118458582' and it then takes the first 3 characters.
If you are trying to take the first three digits and then convert to a number you can use try:
select substring('00118458582', 1,3::numeric)
it might actually be:
select substring('00118458582', 1,3)::numeric
I don't have a way to test right now...
lpad() refers to the total length of the returned value. So I think you want:
select lpad(00118458582::text, 12, '0'::text)
If you always want exactly 3 zeros before, then just concatenate them:
select '000' || 00118458582::text

How to correctly use InStr with ActivePivot?

I am trying to use the INSTR() function with ActivePivot. I am testing by using an Instr call that should always return > 0.
Here is my initial MDX query that works fine:
SELECT
{
{[CODE].[ALL].[AllMember]}
} ON ROWS
FROM [Cube]
WHERE ([Measures].[contributors.COUNT])
Here is my test InStr query:
SELECT
NON EMPTY
Generate
(
[CODE].[ALL].[AllMember]
,(
Instr
(
"Test"
,"es"
) > 0
)
)ON ROWS
FROM [Cube]
WHERE ([Measures].[contributors.COUNT])
Please can you help me create a working example for the Instr MDX query in ActivePivot?
Many thanks
Edit: What I wanted to do
SELECT
NON EMPTY Hierarchize({[CODE].[CODE].Members}) ON ROWS,
NON EMPTY Hierarchize({Filter([RELEVANCE].Members, InStr([RELEVANCE].CurrentMember.Name, "n/a") > 0)}) ON COLUMNS
FROM [Cube]
WHERE ([Measures].[contributors.COUNT])
I'm not sure about what you try to achieve with your MDX but here is an example which may be helpful:
Before, I consider all places with a positive contributors.COUNT:
SELECT
NON EMPTY Hierarchize({Filter([PlaceDimension].[Continent].Members, [Measures].[contributors.COUNT] > 0)}) ON ROWS
FROM [TwitterCube]
WHERE ([Measures].[contributors.COUNT])
After, I keep only places with an "a" in their name:
SELECT
NON EMPTY Hierarchize({Filter([PlaceDimension].[Continent].Members, InStr([PlaceDimension].CurrentMember.Name, "a") > 0)}) ON ROWS
FROM [TwitterCube]
WHERE ([Measures].[contributors.COUNT])

SQL DB2 null calculation causing problems

I have the following SQL:
Select dmvndn "Vendor Number", IFNULL(sum(dmsls) / sum(dmprc), 0) "Calculation"
From MyFile
Group By dmvndn
However, when i run this, i am still getting null records in my "Calculation" field.
I have also tried the COALESCE function, which returns the same results. I get some records as 0, and some records are blank (or, null).
Both fields are of type P, which i am told is packed numeric.
any ideas or suggestions?
Edit 1
It seems that the problem is not with either of these fields being NULL, it is that one or both fields are 0. And when i divide by zero, i get the empty / blank result.
Try
Sum(IFNULL(dmsls,0)) / Sum(IFNULL(dmprc,0))
A trick of this kind helps me in MS SQL Server:
Select
dmvndn "Vendor Number",
IFNULL(sum(dmsls) / NULLIF(sum(dmprc), 0), 0) "Calculation"
From MyFile
Group By dmvndn
I wonder if it can't help you in DB2.
UPDATE: an explanation.
Basically, it replaces the divisor with NULL if it's 0. And you may probably know that when at least one of the operands is NULL, the result of the operation becomes NULL as well.
To account for the result being NULL you already had your IFNULL on the result. It didn't make much difference then, because none of the operands was likely to be NULL. However, now using IFNULL makes perfect sense.