Problem/Motivation
I'm not certain if this is a documentation issue, or if Views is just busted, but the following code does not work:
function my_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
if ($view->id() == 'course_listing') {
$title_alias = 'alias_to_content_table.title';
$query->addGroupBy($title_alias);
}
}
I can see in the debugger that the code executes for the view of that ID, and title field is correctly named. But addGroupBy() is simply ignored when the query object actually renders out the query. I'm using code here because using the Views UI's Aggregation settings creates a monster GROUP BY that makes the query useless.
What needs to be true so that calling $query->addGroupBy($title_alias); will actually lead to a query with a GROUP BY? I can't find this documented anywhere, and I can't tell if I need to do more here, or if Views should render the GROUP BY, but is not.
Steps to reproduce
Proposed resolution
TBD
Remaining tasks
Confirm the problem on a supported version of Drupal.
Comments
Comment #2
Torenware commentedI've also put this up on Drupal Answers, if that's a more appropriate place:
Deduping Views by forcing Views to add a simple GROUP BY to a query. This will also explain a bit more as to why I need to do this.
Comment #3
Torenware commentedPart of the problem here is described here: http://stackoverflow.com/questions/25800411/mysql-isnt-in-group-by. Apparently:
I'm not sure how to dedupe these extra rows, but it would appear that the GROUP BY approach is likely impossible :-(
Comment #4
Torenware commentedI don't think there's a general solution of this, but you can get around some of the limitations of GROUP BY through the use of correlated sub-queries.
I was trying to use MIN(entity_id) = n.entity_id as a way of choosing a single row of a group -- a de-duping problem. This cannot work unless you don't use ORDER BY, due to the limits of the standard. But using a sub-query removes the need to JOIN with the additional table:
This will make sure that there is at least one dependent row (our "link_to_course" table) for each course we display. By not using a JOIN, we solve our de-duping problem.
Comment #9
anpolimusExpecting the same issue at my code.
Comment #10
anpolimusI've found how to fix this issue.
Just use 3rd variable at the addField method, called $params and group by would be affected.
Here is how I've done it at my hook_views_query_alter():
Comment #11
anpolimusAnother solution is to add query_tag and use it at the hook_query_TAG_alter().
In this case you are altering SQL query on low level without any additional subqueries from views sql AddField method.
This approach seems to be more stable and flexible.
Comment #12
anpolimusComment #13
robert.duplock commentedIf anyone is experiencing this problem in a custom views filter - I adapted the above solution to fix the groupBy (E.g. it didn't actually groupBy unless I did the following:
¯\_(ツ)_/¯
Comment #14
rcodina@robert.duplock Thank you so much!
Comment #15
chamilsanjeewa commented@robert.duplock It works, Thank you
Comment #16
ihor_allin commented#13 worked for me. Thanx @robert.duplock
Comment #17
liquidcms commentedNot sure what @anpolimus solutions are about.. they use a variable $match_statement but no explanation of what that is.. also not sure why he marked it as closed.
I have used the solution in #13 on numerous views with a bit of trial and error on which field to group on (although it is obvious from the view; not always obvious in the groupby). I think having an Sort added to the view generally messes the solution in #13 up though.
Comment #18
quietone commentedDrupal 8 is no longer supported. Is this reproducible on a supported release?
Comment #19
liquidcms commentedmy post in #17 was re: D9.3. Pretty sure little has changed from D8 to D10 regarding Views' battle with duplicate results.
Comment #20
quietone commented@liquidcms, thanks. It helps us all if you update the issue meta data as well. This is currently filed on an unsupported version of Drupal, 8.4.x.
I am changing the version to 9.5.x.