combine two result set side by side using mdx - mdx

hi i am new to mdx,
i want to combine two select statement resultset (side by side like union) using mdx query,please any body help me to solve this query
first query:
SELECT
{ [Last Year] }
ON COLUMNS,
{ {[Location].[Location].&[7], [Location].[Location].&[12], [Location].[Location].&[11],
[Location].[Location].&[19], [Location].[Location].&[17], [Location].[Location].&[16],
[Location].[Location].&[9], [Location].[Location].&[18] },{[Location].[Location].[All]}}
ON ROWS
FROM [Cube1]
WHERE ( [Measures].[Labour %] )
here [Last Year] is a calculated set
[Last Year]=====
{STRTOMEMBER("[Date].[Month].&["+ cstr(year(now())-2) +"-11-01T00:00:00]"):
(STRTOMEMBER("[Date].[Month].&["+ cstr(year(now())-1) +"-10-01T00:00:00]"))}
2nd query:
WITH MEMBER [Measures].[Budget ] AS IIF(avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),
avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),0.00),
MEMBER [Measures].[YTD] AS IIF(avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null))<>null,
avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null)),0.00),
FORMAT_STRING = "Standard",
BACK_COLOR = CASE WHEN [YTD] = 0 THEN /*White*/16777215 /*White*/
WHEN [YTD] <= [Measures].[Budget ] THEN 65408
WHEN [YTD]<= [Measures].[Budget ] +5 THEN 65535
WHEN [YTD]> [Measures].[Budget ] +5 THEN 255
END,
VISIBLE = 1
SELECT
{ [Measures].[YTD], [Measures].[Budget ] }
ON COLUMNS,
{ { [Location].[Location].&[7], [Location].[Location].&[12], [Location].[Location].&[11], [Location].[Location].&[19], [Location].[Location].&[17], [Location].[Location].&[16], [Location].[Location].&[9], [Location].[Location].&[18] },{[Location].[Location].[All]} }
ON ROWS
FROM [Cube1]
**here ==> [Measures].[YTD], [Measures].[Budget ] are calculated member
i want result like in
coulmns===> ytd,budget,nov,dec,jan,feb.,,,,,,,,,,october and rows ====> locations and total(average of all locations)
please guide me to get solution like mdx query**

Your concept of "UNION" wont work for 2 main reasons:
1. You can't UNION members from different hierarchies. 2. Query structures are different.
Only way to see them "side by side", would be to open the queries in two different windows.
Instead, if you just wanted to see a combined view of measures and members, use either of the queries below:
//Go for this if you want to see the Locations in output
WITH MEMBER [Measures].[Budget ] AS IIF(avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),
avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),0.00),
MEMBER [Measures].[YTD] AS IIF(avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null))<>null,
avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null)),0.00),
FORMAT_STRING = "Standard",
BACK_COLOR = CASE WHEN [YTD] = 0 THEN /*White*/16777215 /*White*/
WHEN [YTD] <= [Measures].[Budget ] THEN 65408
WHEN [YTD]<= [Measures].[Budget ] +5 THEN 65535
WHEN [YTD]> [Measures].[Budget ] +5 THEN 255
END,
VISIBLE = 1
SELECT
{ [Measures].[YTD], [Measures].[Budget ], [Measures].[Labour %] }
ON COLUMNS,
{ [Last Year] }
*
{ { [Location].[Location].&[7],
[Location].[Location].&[12],
[Location].[Location].&[11],
[Location].[Location].&[19],
[Location].[Location].&[17],
[Location].[Location].&[16],
[Location].[Location].&[9],
[Location].[Location].&[18] },
{[Location].[Location].[All]} }
ON ROWS
FROM [Cube1]
OR
//A cleaner one. Go for this if you don't want to see the Locations in output
WITH MEMBER [Measures].[Budget ] AS IIF(avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),
avg([Last Year],IIF(([Measures].[Budget]>0),[Measures].[Budget],null)),0.00),
MEMBER [Measures].[YTD] AS IIF(avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null))<>null,
avg([Last Year], IIF(([Measures].[Labour %]>0),[Measures].[Labour %],null)),0.00),
FORMAT_STRING = "Standard",
BACK_COLOR = CASE WHEN [YTD] = 0 THEN /*White*/16777215 /*White*/
WHEN [YTD] <= [Measures].[Budget ] THEN 65408
WHEN [YTD]<= [Measures].[Budget ] +5 THEN 65535
WHEN [YTD]> [Measures].[Budget ] +5 THEN 255
END,
VISIBLE = 1
SELECT
{ [Measures].[YTD], [Measures].[Budget ], [Measures].[Labour %] }
ON COLUMNS,
{ [Last Year] } ON ROWS
FROM [Cube1]
WHERE
{ { [Location].[Location].&[7],
[Location].[Location].&[12],
[Location].[Location].&[11],
[Location].[Location].&[19],
[Location].[Location].&[17],
[Location].[Location].&[16],
[Location].[Location].&[9],
[Location].[Location].&[18] },
{[Location].[Location].[All]} }

Related

Put variable inside json_extract_path_text in postgresql query

I have following select:
select json_extract_path_text(rules, 'amount', '5', 'percentage')
from promotion_rules
Sample from JSON looks like this:
{
"amount": {
"1": {
"percentage": 1
},
"2": {
"percentage": 3
},
"3": {
"percentage_below_eq": 5,
"percentage_above": 10,
"price": 20
},
"4": {
"percentage_below_eq": 10,
"percentage_above": 15,
"price": 20
}
}
}
I want to use values from other queries/tables/cte inside above json_extract function instead of '5' (or achieve exact effect), how it can be done?
Here's the part of code and fiddle with full data, I can't put it all here because stack tells me that my post i mostly code.
with percentages as (select pr.*, json_object_keys(rules->'amount')::INT as amount
from
promotion_rules pr
where id = 1
)
select
o.id as order_id,
json_extract_path_text(rules, 'amount', o.products_no, 'percentage') as percentage --it doesn't work this way, either with brackets
from orders o
join percentages p on p.amount = o.products_no
https://www.db-fiddle.com/f/oSQ3eW2G3kHgr3xvpHLw9Q/0
json_extract_path expects a list of text parameters.
If you want to use a column that's not text you need to cast it:
json_extract_path_text(rules, 'amount', o.products_no::text, 'percentage')

Get sum as an additional column instead of only column

I'd like to sum up all the order amounts, grouped per user from my database, for a specific set of users.
I'm using .sum() and .groupBy() to do this, like so:
knex('orders')
.select(['id_user', 'order_amount'])
.whereIn('id_user', ['user-foo', 'user-bar'])
.sum('order_amount')
.groupBy('id_user')
This returns the sums:
[ { sum: 500 } ]
[ { sum: 600 } ]
But now there's no way to know which sum corresponds to which user.
This would be my ideal result:
[ { id_user: 'user-foo', sum: 500 } ]
[ { id_user: 'user-bar', sum: 600 } ]
How can I also get the id_user column for each sum?
You'll need to use knex.raw() for that:
knex.select('id_user', knex.raw('SUM(order_amount)')).from('orders').groupBy('id_user');

Postgres sum values from json only if pair of values exist

My json field looks something like this
{
"Ui": [
{
"element": "TG1",
"mention": "in",
"time": 123
},
{
"element": "TG1",
"mention": "out",
"time": 125
},
{ "element": "TG2",
"mention": "in",
"time": 251
},
{
"element": "TG2",
"mention": "out",
"time": 259
},
{ "element": "TG2",
"mention": "in",
"time": 251
}
]
}
I am trying to get the sum of difference of time per element which is as below
| element | Timespent |
| TG1 | 2 |
| TG2 | 8 |
The problem is ideally for every "in" element there should be an "out" element which is clearly not the case in the above example. I want to only calculate the difference of this pair of values and ignore any value that doesn't have a corresponding out to a in. How can I do that?
Below is what I am using to get the time difference
select element, sum(time) as time_spent
from my_table
cross join lateral (
select
value->>'element' as element,
case value->>'mention' when 'in' then -(value->>'time')::numeric else (value->>'time')::numeric end as time
from json_array_elements(json_column->'Ui')) as elements
group by 1
order by 1
I was not sure about you json_column attribute - you need to group by it in order to not mix values between rows, so I included it into window aggregations in CTE part. But you don't have it in your results, so I skipped it in final qry as well. In short - you can check if order number is even and equal to max order number and then just skip it:
select json_column
, e->>'element' element
, case when
mod(lag(i) over (partition by json_column::text ,e->>'element' order by i),2) = 0
and
max(i) over (partition by json_column::text ,e->>'element') = i
then true else false end "skip"
, case when e->>'mention' = 'in' then -(e->>'time')::int else (e->>'time')::int end times
from my_table, json_array_elements(json_column->'Ui') with ordinality o(e,i)
)
select element, sum (times)
from logic
where not skip
group by element
;
element | sum
---------+-----
TG1 | 2
TG2 | 8
(2 rows)

Analysis services Filter function implicitly filters empty elements

I need to filter members from [__Account.Account selection] by some condition regardless if members are empty or not, but Filter() function implicitly excludes empty members. Is this is a bug or a feature? MSDN does not mention such behavior for Filter function.
Any idea how to avoid the issue?
WITH
SET [__Account.Account selection] AS
'{
{
[Account].[Account Number].&[110]
,[Account].[Account Number].&[1130]
,[Account].[Account Number].&[1164]
,[Account].[Account Number].&[1210]
,[Account].[Account Number].&[1300]
,[Account].[Account Number].&[20]
,[Account].[Account Number].&[8500]
,[Account].[Account Number].&[8040]
}
}'
SET [__Account.Account Number_RootMembers_Smart] AS
'{
Filter(
[__Account.Account selection],
1 = 1)}'
SELECT
[__Account.Account Number_RootMembers_Smart] ON ROWS
,{} ON COLUMNS
FROM [Adventure Works]
NOTE: Function Generate() has the same behavior.
NOTE2: By "empty member" I mean member with not value on any measure.
And there are members with measures...
Please try this:
WITH
SET [__Account.Account selection] AS
{
{
[Account].[Account Number].&[110]
,[Account].[Account Number].&[1130]
,[Account].[Account Number].&[1164]
,[Account].[Account Number].&[1210]
,[Account].[Account Number].&[1300]
,[Account].[Account Number].&[20]
,[Account].[Account Number].&[8500]
,[Account].[Account Number].&[8040]
}
* [Account].[Account].[Account].Members
}
SET [__Account.Account Number_RootMembers_Smart] AS
{
Filter(
[__Account.Account selection],
1=1)}
SELECT {} ON COLUMNS,
[__Account.Account Number_RootMembers_Smart] ON ROWS
FROM [Adventure Works]
Notice that I added the [Account].[Account].[Account].Members into the query. Previously since it was not mentioned, the current coordinate was the [All Accounts] member. Since the Account dimension is a parent-child dimension, the All member doesn't exist with 6 of 8 account numbers apparently. Changing the query ensures that the relevant Account and Account Number pair get put together so that all 8 rows exist in the cube space and show up.

Return all levels below a specific member

In the following I was hoping to return all of the tree below the member Engineering.
I'm guessing I'm misusing IS?
Should I be using membervalue?
I thought using the specific member would be more efficient?
WITH
MEMBER [Measures].[LevelName] AS
[Employee].[Employee Department].Level.Name
MEMBER [Measures].[LevelNumber] AS
[Employee].[Employee Department].Level.Ordinal
SELECT
{
FILTER(
[Employee].[Employee Department].AllMembers,
[Employee].[Employee Department].[Department] IS
[Employee].[Employee Department].[Department].&[Engineering]
)
} ON 1,
{
[Measures].[LevelName],
[Measures].[LevelNumber]
} ON 0
FROM [Adventure Works]
Here is the error message:
Executing the query ... Query (10, 3) The Is function expects a level
expression for the 2 argument. A member expression was used. Execution
complete
You don't need to use the FILTER function to obtain all child members belonging to a specific member. Just do something like this instead:
SELECT
{
[Employee].[Employee Department].[Department].&[Engineering].CHILDREN
} ON 1,
...
If you want the entire tree below a specific member, use the DESCENDANTS function:
SELECT
{
DESCENDANTS([Employee].[Employee Department].[Department].&[Engineering],
[Employee].[Employee Department].[Department], AFTER)
} ON 1,
...