Displaying multiple hierarchy levels in an MDX query - mdx

I'm trying to get the following data from a TFS OLAP cube in a single query
[Work Item].[System_ID] | [Work Item].[System_Title] | [Measures].[BaselineWork]
13426 | Do some work | 5
Sounds pretty simple huh? That's what I thought too, but having 0 knowledge of OLAP, TFS and MDX has made this pretty daunting.
So, I can get this...
SELECT
[Measures].[Microsoft_VSTS_Scheduling_BaselineWork] ON COLUMNS,
[Work Item].[System_Id].MEMBERS ON ROWS
FROM [Team System]
WHERE [Work Item].[System_WorkItemType].&[WPS Task]
and this...
SELECT
[Measures].[Microsoft_VSTS_Scheduling_BaselineWork] ON COLUMNS,
[Work Item].[System_Title].MEMBERS ON ROWS
FROM [Team System]
WHERE [Work Item].[System_WorkItemType].&[WPS Task]
but combining the two has got me stumped.

I think this is what you're after:
SELECT
[Measures].[Microsoft_VSTS_Scheduling_BaselineWork] ON COLUMNS,
[Work Item].[System_Title].MEMBERS * [Work Item].[System_Id].MEMBERS ON ROWS
FROM [Team System]
WHERE [Work Item].[System_WorkItemType].&[WPS Task]
The multiplication is a cross join between the System_Title and System_ID sets. There is more information here

Related

After running for 4 years I now get a "Invalid use of Null" error in my MS Access 2010 Database

Out of the blue I have started getting an "Invalid Use of Null". This is now happening on a number of unrelated queries in my database. (MS Access 2010)
The SQL code behind one of the queries is:
INSERT INTO [Vendor List] ( [Vendor Number], [Vendor Name] )
SELECT [2_Onbase_NewVendors].[Vendor Number], [2_Onbase_NewVendors].[Vendor Name]
FROM 2_Onbase_NewVendors LEFT JOIN [Vendor List] ON [2_Onbase_NewVendors].[Vendor Number] = [Vendor List].[Vendor Number]
WHERE ((([2_Onbase_NewVendors].[Vendor Name]) Is Null));
The query is simply looking for a missing "Vendor" and adding it in. This has been working perfectly for the last few years. I had a look at the two tables and at the moment there are no nulls being returned as everything actually matches.
I have checked the references, and they all seem to be correct. There are no "missing" references. This is happening, in both the runtime, and full versions. I am running the full Access version on Windows 10, where those on the runtime version are running Windows 7. We have recently applied Microsoft office updates, but I cant find anything in those that are related. I've spent a few hours surfing the net but can't find anything relevant. Most things on the net appear to be from when people are creating the queries. I have run the compact and repair on both the front and backend databases.
Any suggestions?
I'm inclined to say "Thank Microsoft" - but the query does look a little screwy:
The query is selecting data from the table 2_Onbase_NewVendors and inserting it into the table [Vendor List] - but only where 2_Onbase_NewVendors.[Vendor Name] is null?
Shouldn't this be where [Vendor List].[Vendor Number] is null? (or Vendor Name):
INSERT INTO [Vendor List] ([Vendor Number], [Vendor Name])
SELECT nv.[Vendor Number], nv.[Vendor Name]
FROM 2_Onbase_NewVendors nv LEFT JOIN [Vendor List] vl ON nv.[Vendor Number] = vl.[Vendor Number]
WHERE vl.[Vendor Number] IS NULL
Recommend you always alias tables (as I have done here), as it always improves clarity, both for yourself, and others who have to read your code.

MDX query with multiple filters using OR

I have the following MDX query which I have been asked to extend:
SELECT {} ON COLUMNS,
CROSSJOIN(
[Waterbody].[Waterbody Code].[Waterbody Code],
[Waterbody].[Waterbody Name].[Waterbody Name],
[Waterbody].[Waterbody Type].[Waterbody Type],
filter([Waterbody].[Waterbody Full Name].allmembers,instr([Waterbody].[Waterbody Full Name].currentmember.member_caption,'Test Waterbody Name')>0)
) ON ROWS FROM [Waterbody Data]
There is another column called "Waterbody Name" and I need to return the rows where the the given value is in either "Waterbody Full Name" or "Waterbody Name".
I'm handy enough at SQL but this MDX stuff is completely new to me. I spent a large part of yesterday trying different things but got nowhere. I'd really appreciate some help.
Thanks
John
Just put the members you want to return into a set (noted by curly braces), and that's it. No need for Filter:
SELECT {} ON COLUMNS,
CROSSJOIN(
[Waterbody].[Waterbody Code].[Waterbody Code],
[Waterbody].[Waterbody Name].[Waterbody Name],
[Waterbody].[Waterbody Type].[Waterbody Type],
{
[Waterbody].[Waterbody Full Name].[Waterbody Full Name],
[Waterbody].[Waterbody Full Name].[Waterbody Name]
}
) ON ROWS
FROM [Waterbody Data]
If you are using the MDX window in SQL Server Management Studio to edit your query, you can drag the members from the list in the left to your script. In this case, depending on cube configuration details, the generated syntax may be slightly different - like containing an ampersand, but both should work. However, using this feature of the the MDX window avoids typos.

Select Query has unexpected multiple records (MS Access)

I may just be tired, but I can't seem to figure out what is happening. I have two queries. Query 1 has 10 fields. Query 2 has 5 fields. Fields 1 through 3 are the same in both queries. I am trying to write a select query and simple add field 5 from Query2 to Query1 so my result should be Query1 with an additional field (Query2.field5).
I join the first 3 fields from both queries and choose select all records in query1 and only those in query2 that match. I don't know sql, so I use query designer. I expect to get the same number of records that I have from query 1 but instead I have 3 times or more. Can someone tell me what I am doing wrong. I even tried reversing the joins but still seem to get the same extra records.
Thanks in advance.
Here is the query:
The fields that are in common are DivisionName, SupplierID = VendorID and CommodityName.
SELECT [Part Revenue Exposed Query P1].DivisionName,
[Part Revenue Exposed Query P1].CommodityName,
[Part Revenue Exposed Query P1].SupplierName,
[Part Revenue Exposed Query P1].PartNumber,
[Part Revenue Exposed Query P1].PartDescription,
[Part Revenue Exposed Query P1].BUCode,
[Part Revenue Exposed Query P1].ProductLine,
[Vendor Risk Score Query].VendorScore
FROM [Part Revenue Exposed Query P1] LEFT JOIN [Vendor Risk Score Query]
ON ([Part Revenue Exposed Query P1].DivisionName = [Vendor Risk Score Query].DivisionName)
AND ([Part Revenue Exposed Query P1].SupplierID = [Vendor Risk Score Query].VendorID)
AND ([Part Revenue Exposed Query P1].CommodityName = [Vendor Risk Score Query].CommodityName);
This is most probably because there are multiple records in [Vendor Risk Score Query] matching the condition in [Part Revenue Exposed Query P1]. i.e. if corresponding to one record of [Part Revenue Exposed Query P1] with values:
DivisionName ='TestDiv', SupplierID = 1, CommodityName = 'TestCommodity'
there can be multiple records in [Vendor Risk Score Query] with values
DivisionName ='TestDiv', SupplierID = 1, CommodityName = 'TestCommodity'
then it will return more records than the number of records in [Part Revenue Exposed Query P1]
Check you join condition.
AND ([Part Revenue Exposed Query P1].SupplierID = [Vendor Risk Score Query].VendorID)
Is supplier to vendor correct?
You said the first three fields are the same. But it only shows two the same.

Calculated field with Sum IFF in MS Access 2010: Query and Expression Builder

In MS Access 2010, I successfully wrote a query that gives me the following fields from two seperate tables: [Customer ID], [Product], [Price], [Total Price] and [Payment Method]
A customer could have order different product or use different payment method. Now, I am trying to have a calculated field that will give the total/sum of only the products that were paid online by each customer.
The [Payment Method] code for online is a "D". I used the code builder expression with the following expression:
1) Sum(IIf([Customer ID] = [Customer ID] AND [Payment Method] = "D", [Price], NULL))
However, it keeps on giving me this error message: You tried to execute a query that does not inclide the specified expression "Customer ID" as part of aggregate function.
If I want to do it in SQL (or expression builder) how would I do it? Everything I've tried so far leads me to the same error message.
Edit
My full query is:
SELECT CUSTOMER_INFO.ID AS [Customer ID],
CUSTOMER_INFO.PROD_KEY AS [Product],
CUSTOMER_INFO.PROD_PRICE AS [Price],
CUSTOMER_INFO.SUM_PRICE AS [Total Price],
PAYMENT_TRANZAK.PAY_METHD,
Sum(IIf([Customer ID]=[Customer ID] And [PAY_MTHD]="D",[Price],[IsNull])) AS [Online Total]
FROM CUSTOMER_INFO INNER JOIN PAYMENT_TRANZAK ON (CUSTOMER_INFO.PROD_KEY= PAYMENT_TRANZAK.SSBSECT_CRN) AND (CUSTOMER_INFO.TERM_CODE_KEY = PAYMENT_TRANZAK.DATE_CODE)
WHERE (
((CUSTOMER_INFO.SUM_PRICE)>0) AND ((PAYMENT_TRANZAK.PAY_METHD) Is Not Null) AND ((CUSTOMER_INFO.CUST_CODE)="RE" Or (CUSTOMER_INFO.CUST_CODE)="RW") AND ((CUSTOMER_INFO.DATE_CODE)=[Please enter a transaction date: ]) AND ((CUSTOMER_INFO.ESTS_CODE)="EL") AND ((CUSTOMER_INFO.STST_CODE)="AS")
)
ORDER BY CUSTOMER_INFO.ID;
You're trying to perform aggregation on non-aggregated data. In order to do a sum the function needs something over which to sum; a "group" of data. Hence you will need a Group By clause in there. Adding the clause GROUP BY CUSTOMER_INFO.ID will create a sum of the totals for each customer ID. You can add your payment type clause to the where statement, too, to get the proper payment type logic.
SELECT CUSTOMER_INFO.ID AS [Customer ID]
, Sum([Price]) AS [Online Total]
FROM CUSTOMER_INFO
INNER JOIN PAYMENT_TRANZAK
ON (CUSTOMER_INFO.PROD_KEY= PAYMENT_TRANZAK.SSBSECT_CRN)
AND (CUSTOMER_INFO.TERM_CODE_KEY = PAYMENT_TRANZAK.DATE_CODE)
WHERE (((CUSTOMER_INFO.SUM_PRICE)>0)
AND ((PAYMENT_TRANZAK.PAY_METHD) Is Not Null)
AND ((CUSTOMER_INFO.CUST_CODE)="RE" Or (CUSTOMER_INFO.CUST_CODE)="RW")
AND ((CUSTOMER_INFO.DATE_CODE)=[Please enter a transaction date: ])
AND ((CUSTOMER_INFO.ESTS_CODE)="EL")
AND ((CUSTOMER_INFO.STST_CODE)="AS"))
AND PAYMENT_TRANZAK.PAY_METHD="D"
GROUP BY CUSTOMER_INFO.ID
ORDER BY CUSTOMER_INFO.ID;
Because you are not aggregating all the fields of not all the fields are being grouped by it is not possible to express them in this kind of query. These
CUSTOMER_INFO.PROD_KEY AS [Product]
CUSTOMER_INFO.PROD_PRICE AS [Price]
CUSTOMER_INFO.SUM_PRICE AS [Total Price]
PAYMENT_TRANZAK.PAY_METHD
thus aren't a good match.
But you know your data better than me, maybe there's a way to fit them in logically. that's up to you.
Edit:
You could try a query like this where you don't do any filtering but you jsut do your grouping. This will present everything then you do the filtering on your report or form.
SELECT CUSTOMER_INFO.ID AS [Customer ID]
, CUSTOMER_INFO.CUST_CODE
, Sum(CUSTOMER_INFO.PROD_PRICE) AS [Online Total]
, Sum(CUSTOMER_INFO.SUM_PRICE) as [SumOfSumPrice]
, CUSTOMER_INFO.CUST_CODE
, PAYMENT_TRANZAK.PAY_METHD
, CUSTOMER_INFO.DATE_CODE
, CUSTOMER_INFO.ESTS_CODE
, CUSTOMER_INFO.STST_CODE
FROM CUSTOMER_INFO
INNER JOIN PAYMENT_TRANZAK
ON (CUSTOMER_INFO.PROD_KEY= PAYMENT_TRANZAK.SSBSECT_CRN)
AND (CUSTOMER_INFO.TERM_CODE_KEY = PAYMENT_TRANZAK.DATE_CODE)
GROUP BY CUSTOMER_INFO.ID
, CUSTOMER_INFO.CUST_CODE
, PAYMENT_TRANZAK.PAY_METHD
, CUSTOMER_INFO.DATE_CODE
, CUSTOMER_INFO.ESTS_CODE
, CUSTOMER_INFO.STST_CODE
ORDER BY CUSTOMER_INFO.ID;
In MS SQL SERVER, ORACLE, MS ACCESS you need to add all other fields in select clause into aggregate clause.
It may help to start with what Access Help has to say on the subject :
Jet SQL Help:All fields in the SELECT field list must either be included in the GROUP BY clause or be included as arguments to an SQL aggregate function.This quote from the Help system implies that all references to fields, even within compound references, must either be aggregated (IE. included in one of the aggregate functions listed above) or included in the GROUP BY clause. Any expression which is of either type is considered aggregated. The aggregate functions can only take field reference expressions which resolve to non-aggregated fields (IE. It is equally invalid to aggregate data more than once).
reference
Since aggregate function is anyway aggregating your query, you may try it without group by clause and see.
Or you could include each of those fields. Issue might be mainly in your case, you have two different fields within the IIF yet having nulls not handled. For an aggregate I would use a zero or make sure to have Isnull to sum IIF.
PS: I sent answer from mobile and it seems the full answer has not been published the first time.

MDX: avg advanced use

I am reaching the limit of my basic MDX knowledge on a problem, if anyone has an idea, every help will be welcome
Situation
This is the hierarchy I'd like to deal with. In my fact_table I have a [Measures].[Sales] measure.
[All Management].[TemplateMgt].[CityMgt].[DistricMgt].[StoreMgt]
[All Management].[TMP-00.002].[London].[DistricMgt].[Shoe001]
[All Management].[TMP-00.002].[London].[DistricMgt].[Hat001]
[All Management].[TMP-00.002].[London].[DistricMgt].[Electronic001]
[All Management].[TMP-00.002].[Paris].[DistricMgt].[Shoe001]
[All Management].[TMP-00.002].[Paris].[DistricMgt].[Hat001]
[All Management].[TMP-00.002].[Paris].[DistricMgt].[Electronic001]
[All Management].[TMP-00.002].[Madrid].[DistricMgt].[Shoe001]
[All Management].[TMP-00.002].[Madrid].[DistricMgt].[Hat001]
[All Management].[TMP-00.002].[Madrid].[DistricMgt].[Electronic001]
Problem
For a given CityMgt, I would like to have three values
[Measures].[Cur]: StoreMgt's sales of the given CityMgt (So for Madrid, get the value [Shoe001], [Hat001], [Electronic001])
[Measures].[Avg]: the average sales of StoreMgt group by StoreMgt having the same TemplateMgt AVG([London].[Shoe001] + [Paris].[Shoe001] + [Madrid].[Shoe001])
[Measures].[Max]: the max sales values of StroreMgt having the same TemplateMgt MAX([London].[Shoe001], [Paris].[Shoe001], [Madrid].[Shoe001])
In other word, I'd like to have an output that will have this structure
Shoe001 | Hat001 | Electronic001
----------------------------------------------------
CUR|AVG|MAX | CUR|AVG|MAX | CUR|AVG|MAX
----------------------------------------------------
What I got so far
WITH MEMBER [Measures].[Cur] AS (...)
MEMBER [Measures].[Avg] AS (...)
MEMBER [Measures].[Max] AS (...)
SELECT {[Measures].[Cur], [Measures].[Avg], [Measures].[Max]} ON COLUMNS,
{FILTER({DESCENDANTS([All Management].CurrentMember, [StoreMgt])}, [All Management].Parent.Parent = "Madrid" } ON ROWS
from [MyCube]
My problem is that I don't know what to put in the Member attributes Cur/Avg/Max so my datas can be treated per StoreMgt (a kind of groupby)
If anyone can enligthenme, I will appreciate.
Cordially,
To get the average you can define new hierarchies (attributes if you're on SSAS). One for the country and another for the product type. Once you get them the statistical calculations are a question of playing with the currentmember and the [All].
You can go for another version -> SUM( FILTER(..members, condition), value)... this can be slow, really slow.
In general, for this kind of calculation you can use what we call statistical or utility dimensions (see).
I am not completely sure that following query will work, hope it conveys the idea,
WITH MEMBER [All Management].[Sales_AVG] AS AVG({[All Management].Members},
[Measures].currentMember)
MEMBER [All Management].[Sales_MAX] AS MAX({[All Management].Members},
[Measure].currentMember)
SELECT {[Measures].[Sales]} ON COLUMNS,
{[All Management].Members, [All Management].[Sales_AVG],
[All Management].[sales_Max]} ON ROWS FROM [MYCUBE] WHERE
{DESCENDANTS([All Management].CurrentMember, [StoreMgt])}