Showing posts with label behaviour. Show all posts
Showing posts with label behaviour. Show all posts

Sunday, March 11, 2012

AS2005. Strange MDX behaviour.

Hi, MDX gurus,

I have a unexplainable problem with pretty easy MDX.

Following MDX queries

//
select
Filter([Date].[Date].members,
[Date].[Date].CurrentMember.MemberValue = VBA![dateadd]("yyyy", -2, VBA![Date]()) )
on 0,
{} on 1
from [Adventure Works]

//
select
Filter([Date].[Date].members,
[Date].[Date].CurrentMember.MemberValue = CDate("11.07.2004"))
on 0,
{} on 1
from [Adventure Works]

provide the same result as expected.

This query

//
select
Filter([Date].[Calendar].[Month].members,
[Date].[Date].CurrentMember.MemberValue = CDate("11.07.2004"))
on 0,
{} on 1
from [Adventure Works]

returns as expected one member

but this query

select
Filter([Date].[Calendar].[Month].members,
[Date].[Date].CurrentMember.MemberValue = VBA![dateadd]("yyyy", -2, VBA![Date]()) )
on 0,
{} on 1
from [Adventure Works]

retuns nothing. This is strange, isn't it?
Can anybody explain it?

Thanks in advance,

Vladimir Chtepa

The puzzle for me is not why your fourth query doesn't return anything - I don't think it should - but why the third query does return July 2004. In your third query you're filtering the members on [Date].[Calendar].[Month] and for each one checking the currentmember on [Date].[Date] - but the currentmember should be the All Member on [Date].[Date] in all cases, as the following queries show:

with member measures.test as [Date].[Date].CurrentMember.membervalue

select measures.test on 0,

[Date].[Calendar].[Month].members on 1

from [Adventure Works]

and

with member measures.test as [Date].[Date].CurrentMember.membervalue = CDate("11/07/2004")

select measures.test on 0,

[Date].[Calendar].[Month].members on 1

from [Adventure Works]

Very strange...

Chris

|||

I don't know why 3-d query returns "expected" result.

It will be great If anybody from developer team could explain it.

AS2005. Some questions about AMO behaviour.

If the DimensionAttribute.EstimatedCount is set and Dimension.Update is called, should I call Database.Update?
Should I call Dimension.Update for every dimension or I can only call Database.Update?

If the Partition.EstimatedRowCount is set and Partition.Update is called, schould I call MeasureGroup.Update?

What will be used at aggregation desing Partition.EstimatedRowCount or MeasureGroup.EstimatedRowCount? What Field schould be set?

The Update() method saves the object's properties and collections, except the major children. For example, cube.Update() will save the cube, except its measure groups, perspectives etc; dimension.Update() will save the dimension, except the dimension permissions (its only major children).

The Update methods also has flags to save an object fully (with all its major children):

obj.Update(UpdateOptions.ExpandFull).

In addition, if you are doing structural changes to an object (changes that would invalidate the data and would require re-processing), you will need to save the dependents as well. For example, if you remove an attribute from a dimension, you will need to save all the dependent cubes with that dimension. There is a separate flag for this:

dimension.Update(UpdateOptions.AlterDependents); // this saves the dependent cubes also

(changes to the EstimatedCount and EstimatedRows properties are not structural, you will not need this flag)

> If the DimensionAttribute.EstimatedCount is set and Dimension.Update is called, should I call Database.Update?

No need to call database.Update(). In fact, database.Update() won't save anything from the dimensions/cubes/mining structures.

> Should I call Dimension.Update for every dimension or I can only call Database.Update?

Yes, for each change to a dimension, call dimension.Update(). Alternatively, you can do all the changes to the dimensions without saving them, and call Update(UpdateOptions.ExpandFull) to the database at the end. But this is not a good idea because it saves the full database (including all dimensions, cubes, mining structures, permissions, partitions, everything; not optimal).

> If the Partition.EstimatedRowCount is set and Partition.Update is called, schould I call MeasureGroup.Update?

No need to call measureGroup.Update().

> What will be used at aggregation desing Partition.EstimatedRowCount or MeasureGroup.EstimatedRowCount? What Field schould be set?

Aggregations design requires the following properties to be set:

- EstimatedCount for all attributes for all dimensions used in the MeasureGroup where the AggregationDesign object will be created

- EstimatedRows for the MeasureGroup

Adrian Dumitrascu

|||

Thank you very much for the detailed answer.

If I understand you right, then I don’t need set Partition.EstimatedCount at all.

Is this right?

AggregationDesigns belongs to a MeasureGroup.

And in a Partition I can set one of the MeasureGroup AggregationDesigns.

What does it means?

|||

> If I understand you right, then I don’t need set Partition.EstimatedCount at all. Is this right?

Yes, you don't need to set the Partition.EstimatedCount in order to design aggregations.

> AggregationDesigns belongs to a MeasureGroup. And in a Partition I can set one of the MeasureGroup AggregationDesigns. What does it means?

You can have multiple Partitions share the same AggregationDesign. Unlike in AS2000 where aggregations were per partition and usually those aggregations had the same structure (same attributes used).

Adrian Dumitrascu

Sunday, February 19, 2012

Arithmic Overlflow on division ?

Hi there,
we are experiencing some very unexptected behaviour here (SQL 2k, latest
SPs, different types of hardware).
Since our application is doing approximations we are trying to get as much
detail as possible from the calculations. However, instead of getting better
results with Numeric(38,25) variables, we are running into Arithmetic
Overflows!!?
As one query can say so much more than a thousand words : please try this :
DECLARE @.x numeric(25, 15)
DECLARE @.y numeric(25, 15)
SELECT @.x = 10000000, -- 10 Million
@.y = 1.021208219120586
SELECT x = @.x, y = @.y
SELECT result = @.x / @.y
SELECT inverse = @.y / @.x
SELECT result_via_inv = Convert(Numeric(25, 15), 1) / (@.y / @.x)
As you will see, this gives me some numbers.
Now replace the Numeric() definitions to something more precise (eg. 38, 25)
Can anyobdoy explain this ? I've found that using 25,15 sometimes gives me
overflows too due to the fact that the amounts involved sometimes go over
10^10. Should I use floats and live with the 'loss of precision' ?
Thanks.
Cu
RobySee "Precision, Scale, and Length" in BOL.

> SELECT result = @.x / @.y
The p ans s of the result will be (38, 38), equal p and s. Whatever number
that you try to cast to numeric(p, s) where p = s, will give you an error
except for zero.
-- error
select cast(1 numeric(38, 38))
-- error
select cast(1 numeric(12, 12))
-- no error
select cast(1 numeric(38, 38))

> SELECT inverse = @.y / @.x
The result is zero and zero can be cast to numeric(38, 38)

> SELECT result_via_inv = Convert(Numeric(25, 15), 1) / (@.y / @.x)
Because @.y / @.x is zero, then you have "Divide by zero error encountered."
error.
May be I am wrong here, so I will call for help from Steve Kass.
AMB
"deroby" wrote:

> Hi there,
> we are experiencing some very unexptected behaviour here (SQL 2k, latest
> SPs, different types of hardware).
> Since our application is doing approximations we are trying to get as much
> detail as possible from the calculations. However, instead of getting bett
er
> results with Numeric(38,25) variables, we are running into Arithmetic
> Overflows!!?
> As one query can say so much more than a thousand words : please try this
:
>
> DECLARE @.x numeric(25, 15)
> DECLARE @.y numeric(25, 15)
> SELECT @.x = 10000000, -- 10 Million
> @.y = 1.021208219120586
> SELECT x = @.x, y = @.y
> SELECT result = @.x / @.y
> SELECT inverse = @.y / @.x
> SELECT result_via_inv = Convert(Numeric(25, 15), 1) / (@.y / @.x)
> As you will see, this gives me some numbers.
> Now replace the Numeric() definitions to something more precise (eg. 38, 2
5)
> Can anyobdoy explain this ? I've found that using 25,15 sometimes gives me
> overflows too due to the fact that the amounts involved sometimes go over
> 10^10. Should I use floats and live with the 'loss of precision' ?
> Thanks.
> Cu
> Roby|||Correction,
-- error
select cast(1 numeric(38, 38))
-- error
select cast(1 numeric(12, 12))
-- no error
select cast(0 numeric(38, 38))
AMB
"Alejandro Mesa" wrote:
> See "Precision, Scale, and Length" in BOL.
>
> The p ans s of the result will be (38, 38), equal p and s. Whatever number
> that you try to cast to numeric(p, s) where p = s, will give you an error
> except for zero.
> -- error
> select cast(1 numeric(38, 38))
> -- error
> select cast(1 numeric(12, 12))
> -- no error
> select cast(1 numeric(38, 38))
>
> The result is zero and zero can be cast to numeric(38, 38)
>
> Because @.y / @.x is zero, then you have "Divide by zero error encountered."
> error.
>
> May be I am wrong here, so I will call for help from Steve Kass.
>
> AMB
> "deroby" wrote:
>|||Interesting, another one for the favorites !
So in order to get this working I should make sure the resuling p & s are
what they are to be in the result column.
I should be able to figure that out =)
Thanks !
Cu
Roby
"Alejandro Mesa" wrote:
> Correction,
> -- error
> select cast(1 numeric(38, 38))
> -- error
> select cast(1 numeric(12, 12))
> -- no error
> select cast(0 numeric(38, 38))
>
> AMB
> "Alejandro Mesa" wrote:
>|||I think that my comment was wrong. I know that the result of @.x / @.y can not
be represented in the result precision and scale, but I do not know those
values. If you reduce the scale or cast one of the variables to float, then
you do not get the error.
AMB
"deroby" wrote:
> Interesting, another one for the favorites !
> So in order to get this working I should make sure the resuling p & s are
> what they are to be in the result column.
> I should be able to figure that out =)
> Thanks !
> Cu
> Roby
> "Alejandro Mesa" wrote:
>|||Hi Alejandro,
Here is my best shot at explaining what deroby sees here:
There are 772 decimal types in SQL Server, and the typing
of expressions involving decimals is tricky business!
The topic "Precision, Scale, and Length" describes
the rules for typing arithmetic on decimal types.
The type of <decimal value 1> <operator> <decimal value 2>
is based on the types, not the values, in the expressions.
Since the result of d1/d2 can be much larger than d1 or
require more places after the decimal point than d1, an
attempt is made to choose a result type that avoids both
overflow and inaccuracy. This is not always possible.
For small cases, there is little problem. The result
of numeric(8,4)/numeric(8,4) could range from around
0.000000000001 to 100000000000.0, and the result type
for this expression is numeric(21,13), which avoids
overflow and maximizes correctness, at least by avoiding
truncation to zero. (Note that no decimal type can exactly
represent 1.0/3.0, so we can't have complete accuracy.)
But for something like numeric(38,15)/numeric(38,15), it
is nearly impossible to account for all possibilities.
The result could range in size from around 10^-15/10^23 to 10^23/10^-15,
which is about 76 orders of magnitude. SQL Server tries harder
to avoid overflow than to be accurate (perhaps since overflow causes
a run-time error, but loss of accuracy doesn't). There is only
a "safety" of never reducing the scale below 6 if it
should really be larger. It turns out the result type for
this quotient in this case is numeric(38,6). This type cannot
represent the reciprocal of 10000000, so it is rounded to zero.
You can see what the result precisions and scales are by
converting to varbinary and inspecting the first two bytes
of the result:
DECLARE @.x numeric(25, 15)
DECLARE @.y numeric(25, 15)
SELECT @.x = 10000000 -- 10 Million
SELECT @.y = 1
SELECT
@.y / @.x as quotient,
cast(@.y / @.x as varbinary) as binRep,
cast(substring(cast(@.y / @.x as varbinary),1,1) as tinyint) as prec,
cast(substring(cast(@.y / @.x as varbinary),2,1) as tinyint) as scale
go
DECLARE @.x numeric(38, 15)
DECLARE @.y numeric(38, 15)
SELECT @.x = 10000000 -- 10 Million
SELECT @.y = 1
SELECT
@.y / @.x as quotient,
cast(@.y / @.x as varbinary) as binRep,
cast(substring(cast(@.y / @.x as varbinary),1,1) as tinyint) as prec,
cast(substring(cast(@.y / @.x as varbinary),2,1) as tinyint) as scale
Steve Kass
Drew University
Alejandro Mesa wrote:
>See "Precision, Scale, and Length" in BOL.
>
>
>The p ans s of the result will be (38, 38), equal p and s. Whatever number
>that you try to cast to numeric(p, s) where p = s, will give you an error
>except for zero.
>-- error
>select cast(1 numeric(38, 38))
>-- error
>select cast(1 numeric(12, 12))
>-- no error
>select cast(1 numeric(38, 38))
>
>
>The result is zero and zero can be cast to numeric(38, 38)
>
>
>Because @.y / @.x is zero, then you have "Divide by zero error encountered."
>error.
>
>May be I am wrong here, so I will call for help from Steve Kass.
>
>AMB
>"deroby" wrote:
>
>|||Steve,
Thanks a lot for the explanation and the tip.
Alejandro Mesa
"Steve Kass" wrote:

> Hi Alejandro,
> Here is my best shot at explaining what deroby sees here:
> There are 772 decimal types in SQL Server, and the typing
> of expressions involving decimals is tricky business!
> The topic "Precision, Scale, and Length" describes
> the rules for typing arithmetic on decimal types.
> The type of <decimal value 1> <operator> <decimal value 2>
> is based on the types, not the values, in the expressions.
> Since the result of d1/d2 can be much larger than d1 or
> require more places after the decimal point than d1, an
> attempt is made to choose a result type that avoids both
> overflow and inaccuracy. This is not always possible.
> For small cases, there is little problem. The result
> of numeric(8,4)/numeric(8,4) could range from around
> 0.000000000001 to 100000000000.0, and the result type
> for this expression is numeric(21,13), which avoids
> overflow and maximizes correctness, at least by avoiding
> truncation to zero. (Note that no decimal type can exactly
> represent 1.0/3.0, so we can't have complete accuracy.)
> But for something like numeric(38,15)/numeric(38,15), it
> is nearly impossible to account for all possibilities.
> The result could range in size from around 10^-15/10^23 to 10^23/10^-15,
> which is about 76 orders of magnitude. SQL Server tries harder
> to avoid overflow than to be accurate (perhaps since overflow causes
> a run-time error, but loss of accuracy doesn't). There is only
> a "safety" of never reducing the scale below 6 if it
> should really be larger. It turns out the result type for
> this quotient in this case is numeric(38,6). This type cannot
> represent the reciprocal of 10000000, so it is rounded to zero.
> You can see what the result precisions and scales are by
> converting to varbinary and inspecting the first two bytes
> of the result:
> DECLARE @.x numeric(25, 15)
> DECLARE @.y numeric(25, 15)
> SELECT @.x = 10000000 -- 10 Million
> SELECT @.y = 1
> SELECT
> @.y / @.x as quotient,
> cast(@.y / @.x as varbinary) as binRep,
> cast(substring(cast(@.y / @.x as varbinary),1,1) as tinyint) as prec,
> cast(substring(cast(@.y / @.x as varbinary),2,1) as tinyint) as scale
> go
> DECLARE @.x numeric(38, 15)
> DECLARE @.y numeric(38, 15)
> SELECT @.x = 10000000 -- 10 Million
> SELECT @.y = 1
> SELECT
> @.y / @.x as quotient,
> cast(@.y / @.x as varbinary) as binRep,
> cast(substring(cast(@.y / @.x as varbinary),1,1) as tinyint) as prec,
> cast(substring(cast(@.y / @.x as varbinary),2,1) as tinyint) as scale
>
> Steve Kass
> Drew University
> Alejandro Mesa wrote:
>
>