Hi Team, I'm running into an issue with our LDM a...
# gooddata-cloud
j
Hi Team, I'm running into an issue with our LDM and hoping to get some guidance. We have two datasets —
position_salaries
and
employee_attributes
.
position_salaries
connects to
employees
via
employee_positions
, while
employee_attributes
references
employees
directly. Both relationships are 1:N — one employee can have many salary records and many attribute values. We'd like to display both
position_salaries.salary
and
employee_attributes.attribute_value
in the same table to show all employee-related data in one visualization. When building a table in Analytical Designer, dragging a field from one dataset makes the other dataset unselectable. Is this a known LDM limitation when datasets connect to the same parent via different paths, and is there a recommended way to handle it?
k
Yes, this is a known and expected behavior in GoodData. When two datasets connect to the same parent (
employees
) via different paths, the Analytical Designer can only display objects that share a single, unambiguous relationship path and compatible grain. Since
position_salaries
reaches
employees
via
employee_positions
while
employee_attributes
references
employees
directly, there is no single valid join path connecting both fact datasets together — so GoodData hides one when you select from the other to prevent incorrect results. [Community Slack] Why This Happens The core rules at play are: • Fact datasets should not be connected directly to other fact datasets. • GoodData requires a single, clear path between the objects you want to analyze together. • When multiple valid paths exist between datasets, the engine may pick one arbitrarily or reject the combination entirely. [Community Slack] Recommended Approaches 1. Use a Shared Conformed Dimension Extract
employees
as a proper shared dimension dataset and ensure both
position_salaries
(via
employee_positions
) and
employee_attributes
reference it through a clear, non-ambiguous path. This is the standard pattern for enabling cross-fact filtering and visualization. [Community Slack] 2. Pre-aggregate / Denormalize in Your Data Source If the grain mismatch is fundamental, consider pre-joining
position_salaries
and
employee_attributes
into a single denormalized table (e.g., in dbt) at a shared grain before loading into GoodData. Registering it as a single dataset resolves the cross-fact issue entirely. [Community Slack] 3. Create a Grain-Specific Bridge Dataset Create a separate dataset (often via a SQL view) at the desired grain that joins in the needed fields, and connect it directly to the relevant fact dataset. This avoids dependence on intermediate datasets with ambiguous paths. [Community Slack] 4. Use MAQL BY Clause (Explicit Lifting) As a metric-level workaround, you can use a BY clause in your MAQL metric definition to explicitly connect a metric to a specific dataset's primary key. This doesn't change the physical join path but can help make metrics compatible with attributes from other datasets. [Community Slack] The most robust long-term fix is typically option 1 or 2 — either ensuring a clean shared dimension path in the LDM, or pre-joining at the source. I'd recommend reviewing GoodData's data modeling tutorials and the many-to-many LDM documentation for further guidance on structuring your model correctly. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups. 👀 Our Support team monitors all messages and will jump in if needed.
j
Hi Jill, Our Kapa AI response has definitely valid points but we can confirm the above or give you more precise answer when we'll see your LDM directly. Could you please share your workspace ID or workspace name so we can check? Thank you
m
Hi Jill, if I understand it correctly, your model is roughly this (using the GoodData style of arrows - each pointing from primary key to foreign key):
employees -> employee_positions -> position_salaries
and
employees -> employee_attributes
and the relationships are default 1:N relationships, not explicitly modelled as M:N or bridge relationships. How does your
employee_attributes
look like? And what does each row there represent for a particular employee? Is it attribute_name & attribute_value? Or is it multiple employee attributes in the same row and their evolution over time or something else? With the current model (if I got it right) the issue is that
position_salaries
and
employee_attributes
are two independent 1:N branches under the same parent employee. At the employee level (which is the only thing they have in common), they are both “many” sides. And combining all rows of particular employee attributes with all rows of that employee positions (and salaries) would lead to data explosion and potential multiple counting. There is no natural row-to-row relationship (which row belongs to which) between
employee_attributes
and
employee_positions
therefore GoodData will not allow you to do this. For example, if we have employee E with 3 different positions and 5 different attributes belonging to this one employee, now there is no way for the system to know which employee attribute to assign to which employee position/salary to display it on a table. So the only way would be to do a cartesian product and return 15 rows (each attribute repeated for each position). Depending how your data look like and what you want to analyze, you might try one of the following solutions: • Option A - flatten the employee_attributes into the
employee
dataset ◦ if you instead move the values of
employee_attributes
into the
employee
dataset (each to its own column i.e. employee_name, employee_sex, employee_level etc.) you will be able to use them for filtering and slicing very easily and there will be no risk of multiplication ◦ during this model change you will need to assign single value of each attribute to the employee row (i.e. the most recent one) • Option B - set the employees-employee_attributes as a M:N relationship in GoodData Model ◦ if you really want to be able to do that expansion and multiplication of rows described above (multiply each attribute for each position) then you can allow GoodData to do it by setting the
employees -> employee_attributes
relationship in the Data Model to M:N type. ◦ To do so, in the Modeller edit mode you drag one more arrow between them - this time from
employee_attributes
back to the
employees
(no additional column in the data is needed) ◦ Once you do that, the model will now show a bi-directional arrow (
employees <--> employee_attributes
) and you will be able to filter and slice anything in
employees
,
employee_positions
and
position_salaries
by data in employee attributes, and therefore combine them in a table. But if you are going to display it together in a visualization/table, you are going to get the rows for each employee multiplied (all their attributes X all their positions). I hope this helps.
j
Hi Michael, thank you for your response, that helps!
🙏 1