Reputation: 13374
Here is a basic model with 2 tables in a 1-1 relationship:
CREATE TABLE CountriesNames(countryId INT, countryName VARCHAR(50));
INSERT INTO CountriesNames VALUES
(1, 'France'),
(2, 'Germany'),
(3, 'Italy');
CREATE TABLE CountriesCodes(countryId INT, countryCode VARCHAR(50));
INSERT INTO CountriesCodes VALUES
(1, 'FR'),
(2, 'DE'),
(3, 'IT');
Now creating an SSAS Tabular model from it:
{
"create": {
"database": {
"name": "TEST_CUBE",
"compatibilityLevel": 1500,
"model": {
"name": "Sales",
"culture": "en-US",
"dataSources": [
{
"name": "DS",
"connectionString": "Provider=SQL Server Native Client 11.0;Data Source=.\\MSSQLSERVER01;Integrated Security=SSPI;Initial Catalog=TEST_CUBE",
"impersonationMode": "impersonateServiceAccount"
}
],
"tables": [
{
"name": "Country Name",
"columns": [
{
"name": "Country ID",
"dataType": "int64",
"isHidden": true,
"sourceColumn": "countryId"
},
{
"name": "Country Name",
"dataType": "string",
"sourceColumn": "countryName"
}
],
"partitions": [
{
"name": "Partition",
"mode": "import",
"source": {
"type": "query",
"query": "SELECT * FROM CountriesNames",
"dataSource": "DS"
}
}
]
},
{
"name": "Country Code",
"columns": [
{
"name": "Country ID",
"dataType": "int64",
"isHidden": true,
"sourceColumn": "countryId"
},
{
"name": "Country Code",
"dataType": "string",
"sourceColumn": "countryCode"
}
],
"partitions": [
{
"name": "Partition",
"mode": "import",
"source": {
"type": "query",
"query": "SELECT * FROM CountriesCodes",
"dataSource": "DS"
}
}
]
}
],
"relationships": [
{
"name": "Relation",
"fromTable": "Country Name",
"fromColumn": "Country ID",
"toTable": "Country Code",
"toColumn": "Country ID"
}
]
}
}
}
}
How to query the model with MDX to get only the 3 possible combinations of ("Country Name", "Country Code") ?
The same result as this SQL query:
SELECT
countryName,
countryCode
FROM
CountriesNames cn JOIN
CountriesCodes cc ON cc.countryId = cn.countryId
Which gives:
Country Name | Country Code
---------------------------
France | FR
Germany | DE
Italy | IT
Whereas this naive MDX query returns all the 9 combinations:
SELECT
([Country Name].Children, [Country Code].Children) ON 0
FROM Sales
I suspect a measure is mandatory, but if so I wonder why, probably missing something obvious.
Upvotes: 0
Views: 40
Reputation: 3741
You have right, a measure is mandatory; This is because the engine works this way - decision on engine design level (as DAX and MDX): If you don't select measure, then Tablular generates underhood two separate queries without joins (like this one) - and generate crossjoin:
SET DC_KIND="AUTO";
SELECT
'CountriesCodes'[countryCode]
FROM 'CountriesCodes';
SET DC_KIND="AUTO";
SELECT
'CountriesNames'[countryName]
FROM 'CountriesNames';
The simplest way to return a correct/existing combination is measure countrows('TableName'). now the engine knows it has to use relations.
SET DC_KIND="AUTO";
SELECT
'CountriesNames'[countryName], 'CountriesCodes'[countryCode],
COUNT ( )
FROM 'CountriesCodes'
LEFT OUTER JOIN 'CountriesNames' ON 'CountriesCodes'[countryId]='CountriesNames'[countryId];
You can try to check what is going on yourself using DaxStudio -> Server Timing feature.
One important thing! IF you query column from one table (then the behavior of auto-exist is fired).
And we get 5 insted of 10 occurence.
https://www.sqlbi.com/articles/understanding-dax-auto-exist/
Upvotes: 1