MDX: iif condition on the value of dimension - mdx

I have 1 Virtual cube consists of 2 cubes.
Example of fact table of 1st cube.
id object_id time_id date_id state
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 0
5 11 4 1 0
6 11 7 1 1
7 10 8 1 0
8 11 5 1 0
9 10 7 1 1
10 10 9 1 2
Where State: 0 - Ok, 1 - Down, 2 - Unknown
For this cube I have one measure StateCount it should count States for each object_id.
Here for example we have such result:
for 10 : 3 times Ok , 2 times Down, 1 time Unknown
for 11 : 3 times Ok , 1 time Down
Second cube looks like this:
id object_id time_id date_id status
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 1
5 11 4 1 1
Where Status: 0 - out, 1 - in. I keep this in StatusDim.
In this table I keep records that should not be count. If object have status 1 that means that I have exclude it from count.
If we intersect these tables and use StateCount we will receive this result:
for 10 : 2 times Ok , 1 times Down, 1 time Unknown
for 11 : 2 times Ok , 1 time Down
As far as i know, i must use calculated member with IIF condition. Currently I'm trying something like this.
WITH MEMBER [Measures].[StateTimeCountDown] AS(
iif(
[StatusDimDown.DowntimeHierarchy].[DowntimeStatus].CurrentMember.MemberValue
<> "in"
, [Measures].[StateTimeCount]
, null )
)

The multidimensional way to do this would be to make attributes from your state and status columns (hopefully with user understandable members, i. e. using "Ok" and not "0"). Then, you can just use a normal count measure on the fact tables, and slice by these attributes. No need for complex calculation definitions.

Related

how to calculate the specific accumulated amount in t-sql

For each row, I need to calculate the integer part from dividing by 4. For each subsequent row, we add the remainder of the division by 4 previous and current lines and look at the whole part and the remainders from dividing by 4. Consider the example below:
id val
1 22
2 1
3 1
4 2
5 1
6 6
7 1
After dividing by 4, we look at the whole part and the remainders. For each id we add up the accumulated points until they are divided by 4:
id val wh1 rem1 wh2 rem2 RESULT(wh1+wh2)
1 22 5 2 0 2 5
2 1 0 1 (3/4=0) 3%4=3 0
3 1 0 1 (4/4=1) 4%4=0 1
4 2 0 2 (2/4=0) 2%4=2 0
5 1 0 1 (3/4=0) 3%4=3 0
6 7 1 2 (5/4=1) 5%4=1 2
7 1 0 1 (2/4=0) 2%4=1 0
How can I get the next RESULT column with sql?
Data of project:
http://sqlfiddle.com/#!18/9e18f/2
The whole part from the division into 4 is easy, the problem is to calculate the accumulated remains for each id, and to calculate which of them will also be divided into 4

Calculate scattered rows's average in sql server?

The table looks like below:
testid stepid serverid duration
1 1 1 10
1 2 1 11
2 1 2 12
2 2 2 13
3 1 1 14
3 2 1 15
4 1 2 16
4 2 2 17
4 tests ran on two servers. Each test has 2 steps. I would like to calculate average duration of each step of all tests on the 2 servers given test id. For example, if given test ids are 1 and 2, the final table looks like below:
stepid avg_duration
1 (10 + 12) / 2
2 (11 + 13) / 2
This is just a group by, right?
select stepid, avg(duration)
from t
where testid in (1, 2)
group by stepid;
Note: You might want avg(duration*1.0) if you want "normal" division.

reorder sort_order in table with sqlite

I have this table:
id sort_ord
0 6
1 7
2 2
3 3
4 4
5 5
6 8
Why does this query:
UPDATE table
SET sort_ord=(
SELECT count(*)
FROM table AS pq
WHERE sort_ord<table.sort_ord
ORDER BY sort_ord
)
WHERE(sort_ord>=0)
Produce:
id sort_ord
0 4
1 5
2 0
3 1
4 2
5 4
6 6
I was expecting all sort_ord fields to subtract by 2.
Here is defined: https://www.sqlite.org/isolation.html
About this link i can interpret, you has several instances for one query (update table and select count table) and independent of each other.
When you are in update sort_data(5) id 5, you have new data for read on every "SET sot_ord" (understanding what say about isolation), and now the result is 4.
Every select is a new instance and a new data reading
id sort_ord
0 4
1 5
2 0
3 1
4 2
5 5**
6 8**

Using temporary extended table to make a sum

From a given table I want to be able to sum values having the same number (should be easy, right?)
Problem: A given value can be assigned from 2 to n consecutive numbers.
For some reasons this information is stored in a single row describing the value, the starting number and the ending number as below.
TABLE A
id | starting_number | ending_number | value
----+-----------------+---------------+-------
1 2 5 8
2 0 3 5
3 4 6 6
4 7 8 10
For instance the first row means:
value '8' is assigned to numbers: 2, 3 and 4 (5 is excluded)
So, I would like the following intermediairy result table
TABLE B
id | number | value
----+--------+-------
1 2 8
1 3 8
1 4 8
2 0 5
2 1 5
2 2 5
3 4 6
3 5 6
4 7 10
So I can sum 'value' for elements having identical 'number'
SELECT number, sum(value)
FROM B
GROUP BY number
TABLE C
number | sum(value)
--------+------------
2 13
3 8
4 14
0 5
1 5
5 6
7 10
I don't know how to do this and didn't find any answer on the web (maybe not looking with appropriate key words...)
Any idea?
You can do what you want with generate_series(). So, TableB is basically:
select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA;
Your aggregation is then:
select n, sum(value)
from (select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA
) a
group by n;

How to find count from two joined tables

We have to find count for each risk category for impact level as shown in last result part
Risk Table
RiskID RiskName
----------------------
1 Risk1
2 Risk2
3 Risk3
4 Risk4
5 Risk5
6 Risk6
7 Risk7
8 Risk8
9 Risk9
10 Risk10
11 Risk11
Category Table
Cat_ID Cat_Name
--------------------------
1 Design
2 Operation
3 Technical
Risk_Category table
Risk_ID Category_ID
------------------------
1 1
1 2
2 1
3 1
3 3
4 1
5 2
6 1
7 3
8 1
9 3
10 3
Risk_Impact_Assessment table
Risk_ID Impact_Level Impact_Score
---------------------------------------------
1 High 20
2 Medium 15
3 High 20
4 Low 10
5 High 20
6 High 20
7 High 20
8 Low 10
9 Medium 15
10 Low 15
11 Medium 15
Result should be like this
Cat_Name Impact_Level_High Impact_Level_Medium Impact_Level_Low
-------------------------------------------------------------------------------------
Design 1 1 2
Operation 2
Technical 2 2 1
You probably want to use the group by clause, along with case, eg.:
select
Cat_Name,
sum(case when Impact_Level = 'High' then 1 else 0 end) as [Impact_Level_High],
sum(case when Impact_Level = 'Medium' then 1 else 0 end) as [Impact_Level_Medium],
sum(case when Impact_Level = 'Low' then 1 else 0 end) as [Impact_Level_Low]
from [Risk_Impact_Assessment]
...
group by Cat_Name;
(I left out all the joins, I assume you can write these no problem)
You can use this trick to accomplish a lot of cool things, including parametric sorting and (just like here) complicated aggregate functions with little work.