I built an entityQuery for a custom entity type "vote". I only want to get those votes for a specific poll and those by deputies who are members of a specific fraction. The fraction membership can change over the time of the legislature so we have an additional custom entity of type "fraction_membership" in which the fraction and the time during which the fraction membership was valid can be set. So what we need is a query that gives just the votes of members of the fraction who were members of the fration at the time of the poll.
The valid time of a fraction_membership can be set in two date fields: valid_from and valid_until.
$fractionId = 22;
$pollId = 1234;
$pollDate = '2020-05-10'
$query = \Drupal::entityQuery('vote');
$query->condition('poll', $pollId, '=');
$query->range(0, 100);
$query->sort('id, 'DESC');
$query->condition('mandate.entity.fraction_membership.entity.fraction', fractionId);
$query->condition(
$query->orConditionGroup()
->notExists('mandate.entity.fraction_membership.entity.valid_from')
->condition('mandate.entity.fraction_membership.entity.valid_from', $pollDate, '<=')
);
$query->condition(
$query->orConditionGroup()
->notExists('mandate.entity.fraction_membership.entity.valid_until')
->condition('mandate.entity.fraction_membership.entity.valid_until', $pollDate, '>=')
);
There are two fraction_membership entities connected to a single mandate of a specific deupty because he changed his fraction membership:
The entries in fraction_membership table:
| id | fraction | valid_from | valid_until
| 123 | 22 | NULL | 2019-09-27
| 456 | 231 | 2019-09-28 | NULL
The problem: with fraction 22 and poll date '2020-05-10' set as filters the vote of the deputy finds it's way into the result although there was no valid fraction membership at this time. The valid_until date for the fraction membership with fraction 22 (= 2019-09-27) is smaller than the poll date (= 2020-05-10). Fpr the given poll the vote of the deputy should only be in the results if the filter for the fraction was set to 231.
I checked the resulting query and for me it looks as if far too many joins are added. Could it be that this is the problem or did I make something wrong?
The resulting SQL query:
SELECT "base_table"."id" AS "id", "base_table"."id" AS "base_table_id"
FROM
{aw_vote_vote} "base_table"
INNER JOIN {aw_vote_vote} "aw_vote_vote" ON [aw_vote_vote].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates" ON [candidacies_mandates].[id] = [aw_vote_vote].[mandate]
INNER JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership" ON [candidacy_mandate__fraction_membership].[entity_id] = [candidacies_mandates].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership" ON [fraction_membership].[id] = [candidacy_mandate__fraction_membership].[fraction_membership_target_id]
INNER JOIN {fraction_membership} "fraction_membership_2" ON [fraction_membership_2].[id] = [fraction_membership].[id]
LEFT JOIN {aw_vote_vote} "aw_vote_vote_2" ON [aw_vote_vote_2].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_2" ON [candidacies_mandates_2].[id] = [aw_vote_vote_2].[mandate]
LEFT JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership_2" ON [candidacy_mandate__fraction_membership_2].[entity_id] = [candidacies_mandates_2].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_3" ON [fraction_membership_3].[id] = [candidacy_mandate__fraction_membership_2].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_4" ON [fraction_membership_4].[id] = [fraction_membership_3].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_3" ON [candidacies_mandates_3].[id] = [aw_vote_vote_2].[mandate]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_5" ON [fraction_membership_5].[id] = [candidacy_mandate__fraction_membership_2].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_6" ON [fraction_membership_6].[id] = [fraction_membership_5].[id]
LEFT JOIN {aw_vote_vote} "aw_vote_vote_3" ON [aw_vote_vote_3].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_4" ON [candidacies_mandates_4].[id] = [aw_vote_vote_3].[mandate]
LEFT JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership_3" ON [candidacy_mandate__fraction_membership_3].[entity_id] = [candidacies_mandates_4].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_7" ON [fraction_membership_7].[id] = [candidacy_mandate__fraction_membership_3].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_8" ON [fraction_membership_8].[id] = [fraction_membership_7].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_5" ON [candidacies_mandates_5].[id] = [aw_vote_vote_3].[mandate]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_9" ON [fraction_membership_9].[id] = [candidacy_mandate__fraction_membership_3].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_10" ON [fraction_membership_10].[id] = [fraction_membership_9].[id]
WHERE ("aw_vote_vote"."poll" = :db_condition_placeholder_0) AND ("fraction_membership_2"."fraction" = :db_condition_placeholder_1) AND (("fraction_membership_4"."valid_from" IS NULL) or ("fraction_membership_6"."valid_from" >= :db_condition_placeholder_2)) AND (("fraction_membership_8"."valid_until" IS NULL) or ("fraction_membership_10"."valid_until" <= :db_condition_placeholder_3))
GROUP BY base_table.id
ORDER BY "base_table"."id" DESC
LIMIT 100 OFFSET 0