For posting purposes, I have removed all sorting, entity relationships, extra fields etc etc from Main View.
Main view returns 1200 rows
Subselect returns 176 rows
After aggregation the main view should display only 176 rows
I am trying to achieve this SQL using views API
SELECT
node.nid,
c.field_parent_component_tid as comp_id,
env.field_mig_details_env_tid as env_id,
migdate.field_mig_details_mig_date_value AS d
FROM node node
LEFT JOIN field_data_field_parent_component c
ON node.nid = c.entity_id
LEFT JOIN field_data_field_mig_details_env env
ON node.nid = env.entity_id
LEFT JOIN field_data_field_mig_details_mig_date migdate
ON node.nid = migdate.entity_id
JOIN (
SELECT
c_sub.field_parent_component_tid as comp_id,
env_sub.field_mig_details_env_tid as env_id,
MAX(date_sub.field_mig_details_mig_date_value) AS maxdate
FROM node subnode
LEFT JOIN field_data_field_parent_component c_sub
ON subnode.nid = c_sub.entity_id
LEFT JOIN field_data_field_mig_details_env env_sub
ON subnode.nid = env_sub.entity_id
LEFT JOIN field_data_field_mig_details_mig_date date_sub
ON subnode.nid = date_sub.entity_id
WHERE
(subnode.status = '1')
AND (subnode.type IN ('migration_details'))
AND (c_sub.field_parent_component_tid IS NOT NULL)
GROUP BY
comp_id,
env_id
) query2 ON c.field_parent_component_tid = comp_id
AND env.field_mig_details_env_tid = env_id
AND migdate.field_mig_details_mig_date_value = maxdate
So, In hook_views_query_alter(&$view, &$query)
I do this code to generate the subselect with all the aggregation
$subquery = db_select('node', 'subnode');
//Set up all the joins to get access to the fields
$subquery->leftjoin('field_data_field_parent_component', 'c', 'subnode.nid = c.entity_id');
$subquery->leftjoin('field_data_field_mig_details_mig_date', 'migTbl', 'subnode.nid = migTbl.entity_id');
$subquery->leftjoin('field_data_field_mig_details_env', 'e', 'subnode.nid = e.entity_id');
//now select the fields that will show up on the SELECT statement
$subquery->fields('c', array('field_parent_component_tid',));
$subquery->fields('e', array('field_mig_details_env_tid',));
$subquery->addExpression('MAX(migTbl.field_mig_details_mig_date_value)', 'maxdate');
//This will generate the WHERE clauses
$subquery->condition('subnode.status', 1);
$subquery->condition('subnode.type', 'migration_details');
//Lastly the grouping
$subquery->groupBy('c.field_parent_component_tid, e.field_mig_details_env_tid');
//Run the query, store in results so I can add it to main query
$result = $subquery->execute();
Then I add the subselect to the main view with the following code
$compAlias = $query->tables['node']['field_data_field_parent_component']['alias'];
$join = new views_join('$subquery', 'node', 'field_parent_component_tid', $compAlias.'.field_parent_component_tid');
//$join->definition = array('table' => $subquery, 'left_field' => 'field_parent_component_tid', 'field' => 'field_parent_component_tid', 'left_table' => 'node');
$join->extra_type = 'AND';
$join->table = $subquery;
$join->left_field = $compAlias.'.field_parent_component_tid';
$join->field = 'field_parent_component_tid';
$join->type = 'INNER';
//$join->adjusted = true;
//$join->extra = $WHAT DO I USE HERE??? = field_mig_details_env_tid';
// AND $WHAT DO I USE HERE??? = maxdate';
//dpm($join);
//Add the subquery as another "table" to the main query
$query->add_relationship('query2', $join, $subquery);
So far so good, the SQL generated in my view looks good, but I need to add an $join->extra
whit the equivilant of
AND env.field_mig_details_env_tid = env_id
AND migdate.field_mig_details_mig_date_value = maxdate
If I look at the generated SQL so far it looks like this:
SELECT
node.nid AS nid,
node_field_data_field_mig_parent_x_ref.nid AS node_field_data_field_mig_parent_x_ref_nid,
'node' AS field_data_field_parent_component_node_entity_type,
'node' AS field_data_field_mig_details_env_node_entity_type,
'node' AS field_data_field_mig_details_mig_date_node_entity_type,
'node' AS field_data_title_field_node_entity_type
FROM
{node} node
LEFT JOIN {field_data_field_mig_parent_x_ref} field_data_field_mig_parent_x_ref
ON node.nid = field_data_field_mig_parent_x_ref.entity_id
AND (field_data_field_mig_parent_x_ref.entity_type = 'node'
AND field_data_field_mig_parent_x_ref.deleted = '0')
LEFT JOIN {node} node_field_data_field_mig_parent_x_ref
ON field_data_field_mig_parent_x_ref.field_mig_parent_x_ref_target_id = node_field_data_field_mig_parent_x_ref.nid
INNER JOIN {field_data_field_parent_component} field_data_field_parent_component
ON node.nid = field_data_field_parent_component.entity_id
AND (field_data_field_parent_component.entity_type = 'node'
AND field_data_field_parent_component.deleted = '0')
INNER JOIN (
SELECT c.field_parent_component_tid AS field_parent_component_tid, e.field_mig_details_env_tid AS field_mig_details_env_tid, MAX(migTbl.field_mig_details_mig_date_value) AS maxdate
FROM
{node} subnode
LEFT OUTER JOIN {field_data_field_parent_component} c ON subnode.nid = c.entity_id
LEFT OUTER JOIN {field_data_field_mig_details_mig_date} migTbl ON subnode.nid = migTbl.entity_id
LEFT OUTER JOIN {field_data_field_mig_details_env} e ON subnode.nid = e.entity_id
WHERE (subnode.status = '1') AND (subnode.type = 'migration_details')
GROUP BY c.field_parent_component_tid, e.field_mig_details_env_tid)
query2 ON
field_data_field_parent_component.field_parent_component_tid = query2.field_parent_component_tid
WHERE (( (node.status = '1') AND (node.type IN ('migration_details')) AND (field_data_field_parent_component.field_parent_component_tid = '141') ))
If I look at the $query->tables, I don’t see that date table, I don’t see the environement table/ How would I add these??