how to get min or max date on columns in mdx query - date

what mdx query logic could i implement for this example to get two rows in result set for hrid = 1 with 1/1/16 as min date(start) for first row where someattribut shows up on column with value 'A'
and 1/15/16 as min date(start) for second row where someattribute has value of 'B' and measure.whatevers has its aggregation for whatever data corresponds to that dimension row.
Im trying to just look at january 2016
everything ive tried i seem to get min date values of 1/1/1900 or both rows have value of 1/1/2016 or i get errors since i cant figure it out.
heres my mdx sample:
WITH MEMBER [Measures].[Start] as
(
-- min date that the combination of someattribute and hrid have certain
-- value withing the range of the where clause restriction of january 2016
SELECT {
[Measures].[Start]
, [Measures].[Whatevers]
} ON COLUMNS
, NON EMPTY {
[Agent].[HRID].children
* [Agent].[someAtribute].Members
} ON ROWS
FROM [RADM_REPORTING]
WHERE (
[Date].[Date View].[Month].&[201601]
)

this works, but it feels kind of like a hack or maybe it feels like its not robust, I am not familiar enough with mdx to be able to make that call.
WITH MEMBER [Measures].[Start] as
filter([Date].[Date View].[Month].&[201601].children,
[Measures].[Whatevers]).item(0).membervalue

Here is a potential direction that is more general:
WITH
MEMBER [Measures].[Start] AS
Min
(
(EXISTING
[Date].[Date].[Date].MEMBERS)
,IIF
(
[Measures].[Internet Sales Amount] = 0
,NULL
,[Date].[Date].CurrentMember.MemberValue
)
)
SELECT
NON EMPTY
{
[Measures].[Start]
,[Measures].[Internet Sales Amount]
} ON COLUMNS
,NON EMPTY
[Product].[Product Categories].[Product] ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2005];
It gives the following:

Related

PSQL crosstabs count(*) returning NULL

I have two issues:
I am trying to create a pivot table using the crosstabs tablefunc but all of the queries I've tried are returning NULL for all values.
I have two grouping variables (airport code and date) that are in one row of data that need to be separate columns in the pivot table, but I can only seem to get one to work.
I have gotten the pivot table to partially work by ignoring the date value for the moment. When I leave 'yyyymm' out of my query, the setup of my output table is okay, but the values don't calculate properly.
The data: I have rows with various airport codes, aircraft user and engine codes, flight identifiers, and year/month values. Each row counts for one flight. A simplified example looks like this:
ident
primary_fa
user_engn
yyyymm
20191122-AFR-23
MKE
O_O
201911
20191210-ASH-61
N90
T_R
201912
20200120-EDV-2
MKE
C_J
202001
20200811-FLC-148
A90
O_O
202008
I need my output table to count the number of arrivals for each user engine combo grouped by airport code and yyyymm. So the rows would be each airport code (primary_fa), yyyymm and columns would be user_engn codes (O_O, T_R, C_J, etc.) with counts for the number of flights per user_engn.
My goal output would look something like this:
primary_fa
yyyymm
C_J
T_R
O_O
MKE
201911
1
0
1
N90
201912
0
1
0
A90
202008
0
0
1
But I am getting this (because I have to ignore the date portion to even get this far):
primary_fa
C_J
T_R
O_O
MKE
NULL
NULL
NULL
N90
NULL
NULL
NULL
A90
NULL
NULL
NULL
I've tried a lot of different versions of the crosstabs query and the closest I have gotten to correct is this:
SELECT *
FROM crosstab(
'SELECT primary_fa as locid,
yyyymm,
count(*)
FROM fy20_keeps_emdf
GROUP BY primary_fa, yyyymm
ORDER BY 1,2',
'VALUES (''C_J''),(''O_O''),(''T_R'')')
AS (primary_fa varchar,
C_J bigint,
O_O bigint,
T_R bigint);
Am I missing something obvious or do I need to do more data manipulation to get this to work?

SQL: How to select first record per day, assuming that each day contains more than 1 value

I am trying to write a SQL query where the results would show the first value (ID) per user per day for the last year.
I tried using the query below and am able to get results for one day but when I try to change the time range to > 2021-06-01, it does not give me the results I expect.
select * from table
where value in
(
SELECT min(value)
FROM table
WHERE valueid = x
group by user
) and Time = '2022-05-30' and value is not null

MDX: Define dimension sub set and show the total

Since in MDX you can specify the member [all] to add the aggregation between all the members of the dimension, if I want to show the totals of a certain measure I can build a query like
SELECT {
[MyGroup].[MyDimension].[MyDimension].members,
[MyGroup].[MyDimension].[all]
} *
[Measures].[Quantity] on 0
FROM [MyDatabase]
Now I want to filter MyDimension for a bunch of values and show the total of the selected values, but of course if I generate the query
SELECT {
[MyGroup].[MyDimension].[MyDimension].&[MyValue1],
[MyGroup].[MyDimension].[MyDimension].&[MyValue2],
[MyGroup].[MyDimension].[all]
} *
[Measures].[Quantity] on 0
FROM [MyDatabase]
it shows the Quantity for MyValue1, MyValue2 and the total of all MyDimension members, not just the ones I selected.
I investigated a bit and came up to a solution that include the generation of a sub query to filter my values
SELECT {
[MyGroup].[MyDimension].[MyDimension].members, [MyGroup].[MyDimension].[all]
} * [Measures].[Quantity] ON 0
FROM (
SELECT {
[MyGroup].[MyDimension].[MyDimension].&[MyValue1],
[MyGroup].[MyDimension].[MyDimension].&[MyValue2]
} ON 0
FROM [MyDatabase]
)
Assuming this works, is there a simplier or more straight forward approach to achieve this?
I tried to use the SET statement to define my custom tuple sets but then I couldn't manage to show the total.
Keep in mind that in my example I kept things as easy as possible, but in real cases I could have multiple dimension on both rows and columns as well as multiple calculated measures defined with MEMBER statement.
Thanks!
What you have done is standard - it is the simple way!
One thing to bear in mind when using a sub-select is that it is not a full filter, in that the original All is still available. I think this is in connection with the query processing of the clauses in mdx - here is an example of what I mean:
WITH
MEMBER [Product].[Product Categories].[All].[All of the Products] AS
[Product].[Product Categories].[All]
SELECT
[Measures].[Internet Sales Amount] ON 0
,NON EMPTY
{
[Product].[Product Categories].[All] //X
,[Product].[Product Categories].[All].[All of the Products] //Y
,[Product].[Product Categories].[Category].MEMBERS
} ON 1
FROM
(
SELECT
{
[Product].[Product Categories].[Category].&[4]
,[Product].[Product Categories].[Category].&[1]
} ON 0
FROM [Adventure Works]
);
So line marked X will be the sum of categories 4 and 1 but line Y will sill refer to the whole of Adventure Works:
This behavior is useful although a little confusing when using All members in the WITH clause.

Min value with GROUP BY in Power BI Desktop

id datetime new_column datetime_rankx
1 12.01.2015 18:10:10 12.01.2015 18:10:10 1
2 03.12.2014 14:44:57 03.12.2014 14:44:57 1
2 21.11.2015 11:11:11 03.12.2014 14:44:57 2
3 01.01.2011 12:12:12 01.01.2011 12:12:12 1
3 02.02.2012 13:13:13 01.01.2011 12:12:12 2
3 03.03.2013 14:14:14 01.01.2011 12:12:12 3
I want to make new column, which will have minimum datetime value for each row in group by id.
How could I do it in Power BI desktop using DAX query?
Use this expression:
NewColumn =
CALCULATE(
MIN(
Table[datetime]),
FILTER(Table,Table[id]=EARLIER(Table[id])
)
)
In Power BI using a table with your data it will produce this:
UPDATE: Explanation and EARLIER function usage.
Basically, EARLIER function will give you access to values of different row context.
When you use CALCULATE function it creates a row context of the whole table, theoretically it iterates over every table row. The same happens when you use FILTER function it will iterate on the whole table and evaluate every row against the filter condition.
So far we have two row contexts, the row context created by CALCULATE and the row context created by FILTER. Note FILTER use the EARLIER to get access to the CALCULATE's row context. Having said that, in our case for every row in the outer (CALCULATE's row context) the FILTER returns a set of rows that correspond to the current id in the outer context.
If you have a programming background it could give you some sense. It is similar to a nested loop.
Hope this Python code points the main idea behind this:
outer_context = ['row1','row2','row3','row4']
inner_context = ['row1','row2','row3','row4']
for outer_row in outer_context:
for inner_row in inner_context:
if inner_row == outer_row: #this line is what the FILTER and EARLIER do
#Calculate the min datetime using the filtered rows
...
...
UPDATE 2: Adding a ranking column.
To get the desired rank you can use this expression:
RankColumn =
RANKX(
CALCULATETABLE(Table,ALLEXCEPT(Table,Table[id]))
,Table[datetime]
,Hoja1[datetime]
,1
)
This is the table with the rank column:
Let me know if this helps.

MDX Query with Date Range Filter

I am new to the MDX queries. I am writing a MDX query to select a Measure value across months and I am putting date Range as filter here just to restrict no of Months returned. For eg I want Sales Revenue for each month in Date Range of 01-Jan-2014 to 30-Jun-2014. Ideally, it should give me sales value for six months i.e Jan, Feb, Mar, Apr, May and June. However when i write below query, I get error. PFB the below enter code here`ow query.
Select NON EMPTY {[Measures].[Target Plan Value]} ON COLUMNS,
NON EMPTY {[Realization Date].[Hierarchy].[Month Year].Members} ON ROWS
From [Cube_BCG_OLAP]
( { [Realization Date].[Hierarchy].[Date].&[20140101] :
[Realization Date].[Hierarchy].[Date].&[20141231] })
The error I get is The Hierarchy hierarchy already appears in the Axis1 axis. Here Date and Month Year belong to same dimension table named as Realization Date. Please help me. Thanks in advance.
You were missing the WHERE clause but I guess that was a typo. As your error message tells, you can't have members of the same hierarchy on two or more axes. In situations like this, you can use something like below which in MDX terminology is called Subselect.
Select NON EMPTY {[Measures].[Target Plan Value]} ON COLUMNS,
NON EMPTY {[Realization Date].[Hierarchy].[Month Year].Members} ON ROWS
From (
SELECT
[Realization Date].[Hierarchy].[Date].&[20140101] :
[Realization Date].[Hierarchy].[Date].&[20141231] ON COLUMNS
FROM [Cube_BCG_OLAP]
)
I like the exists function in this situation:
SELECT
NON EMPTY {[Measures].[Target Plan Value]}
ON COLUMNS,
NON EMPTY
EXISTS(
[Realization Date].[Hierarchy].[Month Year].Members
, {
[Realization Date].[Hierarchy].[Date].&[20140101] :
[Realization Date].[Hierarchy].[Date].&[20141231]
}
)
ON ROWS
FROM [Cube_BCG_OLAP]
Select
[Measures].[Target Plan Value]} On Columns
{
[Realization Date].[Hierarchy].[Date].&[20140101].Parent :
[Realization Date].[Hierarchy].[Date].&[20140631].Parent
}
On Rows
From [Cube_BCG_OLAP]
You need to create this same dimension only for filter in the cube, for example, dimension_filter -> hierarchy_filter -> level_filter