I want mondrian to rollup as per my dimension table. For example
fact_table(id int, dim_id)
1 2
2 2
3 1
4 3
dimension_table( dim_id, value)
1 first_value
2 second_value
The last value in fact_table is delibrately not in the list of dimensions
<Cube name="BYT">
<Dimension type="StandardDimension" visible="true"
highCardinality="false" name="d1">
<Hierarchy name="dimension_table" visible="true" hasAll="true">
<Table name="dimension_table">
</Table>
<Level name="dimension" visible="true" column="dim_id"
type="String" uniqueMembers="false" levelType="Regular"
hideMemberIf="Never">
</Level>
</Hierarchy>
</Dimension>
<Measure name="m1" column="id" datatype="Integer"
aggregator="count" visible="true">
</Measure>
<Cube>
when i fire the following query
select [Measure].[m1] on columns, {([d1])} on rows from [BYT]
The result is
- Dimension Measure
- All D1 4
What i would like mondrian to do is something like this
- Dimension Measure
- All D1 3
i.e. count only on the values included in the dimension table
Please suggest a solution. I read through the rollup policy in the documentation but that does not help my case.
If I understand you well, there is mistake in your cube xml.
You should put distinct count instead of count.
<Measure name="m1" column="id" datatype="Integer"
aggregator="distinct count" visible="true">
</Measure>
Hope this helps.
You need to use a NON EMPTY context, which will result in a join with your fact table.
select [Measure].[m1] on columns, NON EMPTY {([d1])} on rows from [BYT]
Related
I'm trying to get the value of the node from XML. Here is a short sample of the XML
<cpCollection moduleId="cc5005f4-f1ea-433e-b187-8b769170eae4" dataId="0a0e2ddf-2a38-4739-9a52-000f9698978f">
<group id="Serialize" name="Serialize">
<property id="Headline">
<value>One, Two, Three</value>
</property>
<property id="Credit">
<value>0.25</value>
</property>
</group>
</cpCollection>
Some of my query is below:
select TOP 1000 I.Attributes.value('#id', 'nvarchar(32)') as item_name,
F.X.value('#id', 'nvarchar(32)') as field_id,
F.X.value('data(.)', 'nvarchar(256)') as field_value,
F.X.value('Deck[1]','NVarChar(512)') AS Deck,
F.X.value('Credit[1]', 'Nvarchar(8)') As Credit
from cpsys_DataCurrent as T
cross apply T.Attributes.nodes('/cpCollection/group') as I(attributes)
cross apply I.attributes.nodes('property') as F(X)
I am not getting the value for Headline or Credit. Just NULL values.
In XPath /cpCollection/group/property[#id='Credit'] returns
<property id="Credit">
<value>0.25</value>
</property>
Hence, try it in this way
F.X.value('[#id="Credit"]', 'Nvarchar(8)') As Credit
ZLK's answer worked.
F.X.value('(.[#id="Credit"]/value/text())[1]','nvarchar(8)') As Credit
DECLARE #cpsys_DataCurrent TABLE ( xmltext XML);
INSERT INTO #cpsys_DataCurrent (xmltext)
VALUES
( N'<cpCollection moduleId="cc5005f4-f1ea-433e-b187-8b769170eae4" dataId="0a0e2ddf-2a38-4739-9a52-000f9698978f">
<group id="Serialize" name="Serialize">
<property id="Headline">
<value>One, Two, Three</value>
</property>
<property id="Credit">
<value>0.25</value>
</property>
</group>
</cpCollection>');
SELECT TOP 1000
T.xmltext.value('(cpCollection/#dataId)[1]', 'nvarchar(32)') as item_name,
T.xmltext.value('(cpCollection/group/#id)[1]', 'nvarchar(32)') as field_id,
T.xmltext.value('data(cpCollection/group/property)[1]', 'nvarchar(256)') as field_value,
T.xmltext.value('(cpCollection/group/property[#id="Headline"]/value)[1]','NVarChar(512)') AS Deck,
T.xmltext.value('(cpCollection/group/property[#id="Credit"]/value)[1]', 'Nvarchar(8)') As Credit
from #cpsys_DataCurrent as T
Result:
item_name field_id field_value Deck Credit
0a0e2ddf-2a38-4739-9a52-000f9698 Serialize One, Two, Three One, Two, Three 0.25
I'm trying to do a left outer join in FetchXML with multiple conditions.
Here is the approximate SQL of what I'm trying to achieve:
SELECT incident.*, externalCheck.*
FROM incident
LEFT OUTER JOIN externalCheck
ON externalCheck.incidentId = incident.incidentId
AND externalCheck.checkType = 1
AND externalCheck.isLatest = 1;
NB: This should always return a 1:1 relationship since our business logic requires that there is only one isLatest for each checkType.
And here is my FetchXML:
<entity name="incident">
<all-attributes />
<link-entity name="externalCheck" from="incidentId" to="incidentId" link-type="outer">
<filter type="and">
<condition attribute="checkType" operator="eq" value="1" />
<condition attribute="isLatest" operator="eq" value="1" />
</filter>
<all-attributes />
</link-entity>
</entity>
The Problem
The problem is that incident records where the right-hand side of the join are null (i.e. there is no externalCheck record) are not being returned, whereas in a left outer join I would expect that the incident record is still returned even if the right-hand side of the join is null.
What I suspect is that FetchXML is converting my filter to a WHERE clause, rather than adding the conditions to the ON clause.
The Question
Can anyone confirm what is happening, and a possible solution?
Your suspicion is correct. But you can overcome from it somewhat.
Fetchxml is flexible & the below snippet will give the results for left outer join with multiple clause.
<entity name="incident">
<all-attributes />
<link-entity name="externalCheck" alias="ext" from="incidentId" to="incidentId" link-type="outer">
<filter type="and">
<condition attribute="checkType" operator="eq" value="1" />
<condition attribute="isLatest" operator="eq" value="1" />
</filter>
</link-entity>
<filter>
<condition entityname="ext" attribute="externalCheckid" operator= "null" />
</filter>
</entity>
The real problem is with externalCheck.*, you cannot get the related entity attributes. Have to remove the <all-attributes /> from link-entity node.
Read more
I am new to Pentaho, Mondrian & MDX. I started to use Pentaho CE 5.0.1 as my OLAP tool. I am struggling with a MDX query and hoping someone can give me some pointers on my issue.
I have the following time dimension mondrian schema:
`<!-- date dimension -->
<Dimension name="Time" type="TimeDimension">
<!-- Year, Quarter, Month, Week, Day -->
<Hierarchy name="YQMD" hasAll="true" allMemberName="All Dates" primaryKey="date_key" type="TimeDimension">
<Table name="dim_date" schema="webportal"/>
<Level name="Year" uniqueMembers="true" column="year4" levelType="TimeYears" type="Numeric"></Level>
<Level name="Quarter" uniqueMembers="false" column="quarter_name" levelType="TimeQuarters" type="String"></Level>
<Level name="Month" uniqueMembers="false" column="month_number" ordinalColumn="month_number" nameColumn="month_number" levelType="TimeMonths" type="Numeric"></Level>
<Level name="Week" column="week_in_month" uniqueMembers="false" levelType="TimeWeeks"></Level>
<Level name="Day" column="day_in_month" uniqueMembers="false" ordinalColumn="day_in_month" nameColumn="day_in_month" levelType="TimeDays" type="Numeric"></Level>
</Hierarchy>
</Dimension>`
I am running this MDX query:
WITH
MEMBER [Measures].[YTD] AS 'SUM(YTD(), [Measures].[Quotation Status])'
SELECT
NON EMPTY {[Measures].[Quotation Status], [Measures].[YTD]} ON COLUMNS,
NON EMPTY {
{[Time.YQMD].[Year].Members},
[Time.YQMD].[Month].Members
} ON ROWS
FROM [Broker Portal]
The MDX query works and returns the following data:
My question(s) are this:
How do I remove the first two lines containing 2015, 2016 in MDX?
How do I remove the the lines for months 03 - 12 for the year 2016?
I suspect something like the following might be heading in the right direction:
WITH
MEMBER [Measures].[YTD] AS
Sum
(
YTD()
,[Measures].[Quotation Status]
)
SELECT
NON EMPTY
{
[Measures].[Quotation Status]
,[Measures].[YTD]
} ON COLUMNS
,NON EMPTY
[Time.YQMD].[Year].MEMBERS
* [Time.YQMD].[Month].[Month].MEMBERS HAVING
[Measures].[Quotation Status] > 0 ON ROWS
FROM [Broker Portal];
I have xml schema description for Pentaho Mondrian. It looks like this:
<Dimension foreignKey="dt" name="dt" type="TimeDimension">
<Hierarchy allMemberName="All" hasAll="true" name="Hierarchy" primaryKey="dt" visible="true">
<View alias="dt_view">
<SQL dialect="generic">select distinct "dt",date_part('year', "dt")::integer AS year, date_part('month', "dt")::integer AS month, date_part('day', "dt")::integer AS day from "world_steel_production"."world_steel_production_data"
</SQL>
</View>
<Level captionColumn="year" column="year" hideMemberIf="Never" levelType="TimeYears" name="Years" type="Integer" uniqueMembers="false"/>
<Level column="month" formatter="capsidea.MemberMonthFormatter" hideMemberIf="Never" levelType="TimeMonths" name="Month" type="Integer" uniqueMembers="false"/>
</Hierarchy>
</Dimension>
<Dimension foreignKey="obj" name="Index">
<Hierarchy allMemberName="All" hasAll="true" name="name_ru" primaryKey="key" visible="true">
<Table name="world_steel_production_dict_obj" schema="world_steel_production"/>
<Level column="key" nameColumn="name_ru" parentColumn="parent_key" hideMemberIf="Never" levelType="Regular" name="Level" type="Integer" uniqueMembers="true"/>
</Hierarchy>
</Dimension>
<Measure aggregator="sum" column="vl" name="Value" visible="true"/>
</Cube>
Our timedimension <Dimension foreignKey="dt" name="dt" type="TimeDimension"> contains two levels: "year" and "month"
When I choose level "year" Mondrian aggregates data by year.
It seems fine, but table world_steel_production_data has two dynamic levels in data which defines columns dl (1 - year dynamic and 4 - month dynamic)
This case when I aggregate data by year level in 1980 contains data with year and month dynamics.
I've read (http://mondrian.pentaho.com/documentation/aggregate_tables.php) that Pentaho can use aggregate table and I want to use them in order to split my month and year dynamics.
I've create two vies for aggregate table purpose
create or replace view world_steel_production.world_steel_production_data_view_year
as
select *
from world_steel_production.world_steel_production_data
where dl = 1
and
create or replace view world_steel_production.world_steel_production_data_view_month
as
select *
from world_steel_production.world_steel_production_data
where dl = 4
But now I'm wandering how to say to Pentaho in my xml schema definition use the first view for year dynamics and second one for month dynamics?
Or maybe there is another way to split year and months dynamics?
I think I've found the solution.
Mondrian has such thing as Closure tables (http://mondrian.pentaho.com/documentation/schema.php#Closure_tables ). At this table you can define how to aggregate in your hierarchy dimension.
What I've done in my situation:
I've created and filled hierarchy table for dates and link this table with data-table in my schema.
Next I've created and filled closure table.
As you can see, I've filled closure table as my world_steel_production_time_hierarchy has no hierarchy at all (time_id = parent_time_id).
And at last I've changed XML data definition.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
My table structure is as follows:
date Id Value
--------------------------------
01/01/2005 50000 5
01/01/2006 50000 6
01/01/2007 50000 7
01/01/2005 50001 8
01/01/2006 50001 9
01/01/2007 50001 10
I would like to output the xml using for xml in SQL Server in the following format:
<Date date = "01/01/2005"> <Id dealId=50000" value="5"/> <Id dealId=50001" value="8"/> </Date> <Date date = "01/01/2006"> <Id dealId=50000" value="6"/> <Id dealId=50001" value="9"/> </Date>
It would be of great help if someone can help me out with the query in SQL Server. I have tried couple of them myself but I am not getting the exact output.
-- using your provided values:
DECLARE #table TABLE ([date] DATE, id INT, value INT);
INSERT #Table VALUES ('01/01/2005',50000,5);
INSERT #Table VALUES ('01/01/2006',50000,6);
INSERT #Table VALUES ('01/01/2007',50000,7);
INSERT #Table VALUES ('01/01/2005',50001,8);
INSERT #Table VALUES ('01/01/2006',50001,9);
INSERT #Table VALUES ('01/01/2007',50001,10);
-- XML Query
-- the outer query groups by date, ensuring each date only shows up once
SELECT
[date] AS '#date',
(
-- The inner query selects all Ids for each date found in the outer query
SELECT id as '#dealId',
value as '#value'
FROM #Table B
WHERE B.date=A.date -- join on date from outer query
FOR XML PATH ('Id'), TYPE
)
FROM #Table A
GROUP BY date
FOR XML PATH ('Date');
-- Produces:
<Date date="2005-01-01">
<Id dealId="50000" value="5"/>
<Id dealId="50001" value="8"/>
</Date>
<Date date="2006-01-01">
<Id dealId="50000" value="6"/>
<Id dealId="50001" value="9"/>
</Date>
<Date date="2007-01-01">
<Id dealId="50000" value="7"/>
<Id dealId="50001" value="10"/>
</Date>
Usually, if I need such a simple xml transformation, I'm using for xml raw:
select
t1.[date],
(
select
t2.[Id] as dealId, t2.[Value]
from Table1 as t2
where t2.[date] = t1.[date]
for xml raw('Id'), type
)
from Table1 as t1
group by t1.[date]
for xml raw('Date')
----------------------
<Date date="2005-01-01">
<Id dealId="50000" Value="5"/>
<Id dealId="50001" Value="8"/>
</Date>
<Date date="2006-01-01">
<Id dealId="50000" Value="6"/>
<Id dealId="50001" Value="9"/>
</Date>
<Date date="2007-01-01">
<Id dealId="50000" Value="7"/>
<Id dealId="50001" Value="10"/>
</Date>
Try it yourself in the sql fiddle demo
Some notes:
You don't have to use # in column names, because for xml raw is attribute-centric by default.
Subquery here is necessary, because you want nested xml and for now it's the only way to get it.
You also have to use type modifier in the subquery to get inner data as xml.