Hi GoodData team, Could you help me understand wh...
# gooddata-cloud
m
Hi GoodData team, Could you help me understand why a different view was used as a driving dataset in the generated query (under Analyse) even if there are no attributes used related to that view? For better context, I am attempting to create a table that lists the matters of a specific firm. On the rows, the following attributes are: • Matter Code (from Matters dataset) • Matter Title (from Matters dataset) • Business Contact Company Name (from Business Contacts dataset, renamed to 'Firm') ◦ Note: there are business contacts linked to the matter • User Name (from Users dataset; renamed to 'Barrister') ◦ Note: joined to Matters via bridge dataset Matter Barristers (M:N) However, when I add the Individual Contact Full Name (from Individual Contacts dataset) and I check the generated query, the main view used was
vw_expense
. The result now shows all matters linked to the specific firm, and have existing expenses. Please let me know if additional information is needed here 🙏 Thanks in advance Query:
Copy code
-- dsId: 8ad48ef0-ece5-4c7d-8fae-a86326beb1f0
SELECT `a_matter_code` AS `l_matter_code`, `a_matter_title` AS `l_matter_title`, `a_business_contact_company_name` AS `l_business_contact_company_name`, `a_individual_contact_full_name` AS `l_individual_contact_full_name`, `a_user_name` AS `l_user_name`, `m_be761a7f9e729d64f471fc11c72446db` AS `m_1`
FROM (SELECT `vw_business_contact`.`business_contact_company_name` AS `a_business_contact_company_name`, `vw_individual_contact`.`individual_contact_full_name` AS `a_individual_contact_full_name`, `vw_matter`.`matter_code` AS `a_matter_code`, `vw_matter`.`matter_title` AS `a_matter_title`, `vw_user`.`user_name` AS `a_user_name`, COUNT(DISTINCT `vw_matter`.`matter_id`) AS `m_be761a7f9e729d64f471fc11c72446db`, TRUE AS `def_m_be761a7f9e729d64f471fc11c72446db`
FROM `fountain_court`.`vw_expense`
INNER JOIN `fountain_court`.`vw_matter` ON `vw_expense`.`matter_id` = `vw_matter`.`matter_id`
INNER JOIN `fountain_court`.`vw_user` ON `vw_expense`.`user_id` = `vw_user`.`user_id`
INNER JOIN `fountain_court`.`vw_matter_contact` ON `vw_expense`.`matter_id` = `vw_matter_contact`.`matter_id`
INNER JOIN `fountain_court`.`vw_business_contact` ON `vw_matter`.`matter_firm_id` = `vw_business_contact`.`business_contact_id`
INNER JOIN `fountain_court`.`vw_individual_contact` ON `vw_matter_contact`.`contact_id` = `vw_individual_contact`.`individual_contact_id`
WHERE `vw_matter`.`matter_is_draft` = 'false'
GROUP BY `vw_matter`.`matter_code`, `vw_matter`.`matter_title`, `vw_user`.`user_name`, `vw_business_contact`.`business_contact_company_name`, `vw_individual_contact`.`individual_contact_full_name`) AS `t2`
WHERE `t2`.`def_m_be761a7f9e729d64f471fc11c72446db` AND `t2`.`a_business_contact_company_name` = 'Winston Taylor International LLP';
k
Why vw_expense Becomes the Driving Dataset This is expected behavior in GoodData, and it's directly related to how your Logical Data Model (LDM) is structured. The Core Reason GoodData's query planner always starts from the fact (lowest-grain) dataset that connects all the requested objects together, and then joins outward to reach the attributes in your insight. [Connection points] In your case, when you add Individual Contact Full Name (from the Individual Contacts dataset), GoodData needs to find a valid join path that connects: • Matters • Business Contacts • Users (via Matter Barristers bridge) • Individual Contacts The only valid path in your LDM that connects all four of these datasets appears to go through
vw_expense
— likely because
vw_expense
is the fact/lowest-grain dataset that has foreign keys linking to matters, users, and (via
vw_matter_contact
) to individual contacts. Without
Individual Contact Full Name
, GoodData could use a different path, but adding it forces the planner to route through
vw_expense
as the common base. [Connection points] This also explains why your results are now filtered to matters with existing expenses — because
vw_expense
is the base table, the
INNER JOIN
to
vw_matter
means only matters that have at least one expense row are returned. What You Can Do To avoid routing through
vw_expense
, you have a few options: 1. Eliminate alternate paths in your LDM so that only the desired path (not through
vw_expense
) remains between Individual Contacts and the other datasets. [Alternate paths] 2. Create a bridge/SQL dataset at the correct grain — for example, a view keyed by
matter_id
that already joins in individual contact fields directly, and connect it to the Matters dataset. This avoids dependence on
vw_expense
as the connecting dataset. [Bridge dataset pattern] 3. Review the relationship directions (arrows) in your LDM — the engine follows the shortest valid path between datasets based on arrow directions. If the only valid path between Individual Contacts and Matters currently goes through
vw_expense
, you need to introduce a direct or alternative connection that does not require it. [LDM relationships] Tip for Debugging You can append
/debug
to the end of the Analyse URL (replacing
/edit
) to download a debug file containing the exact SQL query being generated. This can help you trace which join path is being used and why. [Debug tip] In summary, the root cause is that
vw_expense
is the fact dataset that GoodData identifies as the lowest-grain common connector for all the objects in your insight once Individual Contact Full Name is added. Redesigning the LDM to provide a direct path between Individual Contacts and Matters (without going through
vw_expense
) is the recommended fix. 👍 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.
m
Just to add, the expected behavior is that we should be seeing all the matters linked to the firm, regardless of whether we add the individual contact or not @kapa.ai
j
👀
k
Your expectation is correct — the visualization without Individual Contact Full Name (shown in your new screenshot) displays all matters for the firm, which is the desired behavior. However, adding Individual Contact Full Name causes GoodData to route the query through
vw_expense
as the driving dataset, which then filters results to only matters that have existing expenses via the
INNER JOIN
. This is a known LDM design issue, not a bug in your data. The root cause is that the only valid join path GoodData can find to connect Individual Contacts to the rest of your model goes through
vw_expense
. [Connection points] To achieve your expected behavior (all matters visible regardless of whether Individual Contact is added), you need to provide GoodData with a join path to Individual Contacts that does not go through
vw_expense
. The recommended approaches are: 1. Create a bridge/SQL dataset at
matter
grain
— a view keyed by
matter_id
that directly joins in individual contact fields, connected to the Matters dataset. This gives GoodData a direct path that doesn't require
vw_expense
. 2. Eliminate alternate paths in your LDM so the only valid path between Individual Contacts and Matters is the direct one (not through
vw_expense
). 3. Review arrow directions in your LDM to ensure the relationship between Individual Contacts and Matters is navigable without routing through the expense dataset. [LDM relationships] Without one of these LDM changes, GoodData will continue to route through
vw_expense
whenever Individual Contact Full Name is included, causing the unintended filtering of results. 👍 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 Mira, To start with what I actually verified: I've compared the
/debug
SQLs for both the single-bridge and combined-bridge variants, and that's what let us pinpoint exactly where the behavior stems. With either bridge used alone, the planner correctly anchors on
vw_matter_barrister
or
vw_matter_contact
. The moment both M:N bridges are combined in a single insight, the planner switches to
vw_expense
as the FROM clause — and since that view uses `INNER JOIN`s throughout, results collapse to only matters that have at least one expense row. The reason
vw_expense
gets picked is that your Expenses dataset has direct FK references to both Matters and Users. When the optimizer needs to combine two bridges, it finds it "cheaper" to anchor on that single fact table rather than chain two separate M:N bridges off Matters. As a workaround you can use right now, split it into two insights on the same dashboard — one with Matter Code, Matter Title, Firm, and Barrister, and another with Matter Code, Matter Title, Firm, and Individual Contact Full Name. Apply the
Firm = Winston Taylor International LLP
filter at the dashboard level so it propagates to both, and cross-reference via Matter Code. Both queries will anchor correctly on their respective bridges with no
vw_expense
involvement. The longer-term fix would need to happen in the LDM, specifically the
Expenses → Users
reference. If
Expenses.user_id
represents something semantically distinct from "Barrister" (e.g. the user who logged the expense), modelling it as a separate role/dataset would remove that shortcut and allow a combined insight to work cleanly. We will gladly give you some hints or direct you the way how this could be resolved. However, please note that similar kind of LDM change is outside the scope of what our Support team handles, but our Professional Services team would be well-placed to help with it. If you're interested, feel free to reach out to your account owner Thiago Alves (thiago.alves@gooddata.com) and he can get you connected.
📝 1
I've tested one more workaround that keeps everything in a single table.. In this case no LDM change needed. If you add a metric anchored on the
Matter Barristers
bridge (simplest:
SUM(Barrister Due Days)
, since that fact lives in that dataset), the planner is forced to keep
vw_matter_barrister
in the query and the
vw_expense
shortcut disappears. Verified in
/debug
— FROM becomes
vw_matter_contact
joined directly to
vw_matter_barrister
and
vw_matter
, and the full list of matters for the firm comes back instead of just those with expenses. Trade-off is an extra
Barrister Due Days
column.
📝 1
image.png
m
Thank you so much for your insightful response, @Julius Kos. 🙌 Re LDM fix, I'm not sure if we can remove the
Expenses → Users
reference, as
Expenses.user_id
represents the "Barrister" linked to that expense. We may have visualizations where we filter/group the expenses by barrister
Hi @Julius Kos, just wanted to reach out to you regarding my last response. Do you know if we can have an alternative LDM fix for this one? Thank you in advance 🙏
j
Hi Mira, apologies but at this point, finding a permanent fix would require a deeper review of the LDM and its joins, especially around the
Expenses
Users
relationship, to avoid unintended planner shortcuts. This type of redesign would need to be done from your end as you are better familiar with your analytics and specific reporting needs and this is unfortunately outside the scope of Support and would be better handled by our Professional Services team, who can assess the impact on your existing model and dashboards in detail. As was mentioned - If you’re interested, your account owner Thiago can help arrange this. Thank you for your understanding.
m
Okay got it @Julius Kos, Thank you so much for the assistance 🙂