diff --git a/CRM/Activity/BAO/Activity.php b/CRM/Activity/BAO/Activity.php index 62f50c8290c1..e323eb1bea60 100644 --- a/CRM/Activity/BAO/Activity.php +++ b/CRM/Activity/BAO/Activity.php @@ -717,7 +717,7 @@ public static function &getActivities($input) { $insertSQL = "INSERT INTO {$activityTempTable} (" . implode(',', $insertValueSQL) . " ) "; $order = $limit = $groupBy = ''; - $groupBy = " GROUP BY tbl.activity_id "; + $groupBy = " GROUP BY tbl.activity_id, tbl.activity_type, tbl.case_id, tbl.case_subject "; if (!empty($input['sort'])) { if (is_a($input['sort'], 'CRM_Utils_Sort')) { @@ -804,7 +804,7 @@ public static function &getActivities($input) { INNER JOIN civicrm_activity_contact ac ON ( ac.activity_id = {$activityTempTable}.activity_id ) INNER JOIN civicrm_contact c ON c.id = ac.contact_id WHERE ac.record_type_id = %1 -GROUP BY ac.activity_id +GROUP BY ac.activity_id, ac.contact_id "; CRM_Core_DAO::executeQuery($query, $params); diff --git a/CRM/Campaign/BAO/Survey.php b/CRM/Campaign/BAO/Survey.php index ff49c73629c3..26226a474a68 100644 --- a/CRM/Campaign/BAO/Survey.php +++ b/CRM/Campaign/BAO/Survey.php @@ -479,8 +479,7 @@ public static function voterDetails($voterIds, $returnProperties = array()) { $query = " SELECT contact.id as contactId, $selectClause FROM $fromClause - WHERE $whereClause -Group By contact.id"; + WHERE $whereClause"; $contact = CRM_Core_DAO::executeQuery($query); while ($contact->fetch()) { diff --git a/CRM/Campaign/Form/Survey/Results.php b/CRM/Campaign/Form/Survey/Results.php index 3021fe16e99d..97cc04bbee90 100644 --- a/CRM/Campaign/Form/Survey/Results.php +++ b/CRM/Campaign/Form/Survey/Results.php @@ -61,7 +61,7 @@ public function preProcess() { $this->set('values', $this->_values); } - $query = "SELECT MAX(id) as id, title FROM civicrm_report_instance WHERE name = %1"; + $query = "SELECT MAX(id) as id, title FROM civicrm_report_instance WHERE name = %1 GROUP BY id"; $params = array(1 => array("survey_{$this->_surveyId}", 'String')); $result = CRM_Core_DAO::executeQuery($query, $params); if ($result->fetch()) { diff --git a/CRM/Case/BAO/Case.php b/CRM/Case/BAO/Case.php index ad5b33a74da0..3af84c56a496 100644 --- a/CRM/Case/BAO/Case.php +++ b/CRM/Case/BAO/Case.php @@ -458,7 +458,6 @@ public static function getCaseActivityQuery($type = 'upcoming', $userID = NULL, FROM civicrm_view_case_activity_upcoming ORDER BY activity_date_time ASC, id ASC ) AS upcomingOrdered - GROUP BY case_id ) AS act LEFT JOIN civicrm_option_group aog ON aog.name='activity_type' LEFT JOIN civicrm_option_value aov ON ( aov.option_group_id = aog.id AND aov.value = act.activity_type_id ) @@ -478,7 +477,6 @@ public static function getCaseActivityQuery($type = 'upcoming', $userID = NULL, FROM civicrm_view_case_activity_recent ORDER BY activity_date_time DESC, id ASC ) AS recentOrdered - GROUP BY case_id ) AS act LEFT JOIN civicrm_option_group aog ON aog.name='activity_type' LEFT JOIN civicrm_option_value aov ON ( aov.option_group_id = aog.id AND aov.value = act.activity_type_id ) @@ -759,6 +757,7 @@ public static function getCasesSummary($allCases = TRUE, $userID) { $myCaseWhereClause = " AND case_relationship.contact_id_b = {$userID}"; $myGroupByClause = " GROUP BY CONCAT(case_relationship.case_id,'-',case_relationship.contact_id_b)"; } + $myGroupByClause .= ", case_status.label, status_id, case_type_id"; // FIXME: This query could be a lot more efficient if it used COUNT() instead of returning all rows and then counting them with php $query = " @@ -986,7 +985,7 @@ public static function getCaseActivity($caseID, &$params, $contactID, $context = } $groupBy = " - GROUP BY ca.id "; + GROUP BY ca.id, tcc.id, scc.id, acc.id, ov.value"; $sortBy = CRM_Utils_Array::value('sortBy', $params); if (!$sortBy) { @@ -1246,8 +1245,7 @@ public static function getRelatedContacts($caseID, $skipDetails = FALSE) { LEFT JOIN civicrm_email ce ON ce.contact_id = cc.id AND ce.is_primary= 1 - WHERE cr.case_id = %1 - GROUP BY cc.id'; + WHERE cr.case_id = %1'; $params = array(1 => array($caseID, 'Integer')); $dao = CRM_Core_DAO::executeQuery($query, $params); @@ -1732,7 +1730,7 @@ public static function getCaseActivityDates($caseID, $criteriaParams = array(), if (!empty($criteriaParams['activity_type_id'])) { $where .= " AND ca.activity_type_id = " . CRM_Utils_Type::escape($criteriaParams['activity_type_id'], 'Integer'); $where .= " AND ca.is_current_revision = 1"; - $groupBy .= " GROUP BY ca.activity_type_id"; + $groupBy .= " GROUP BY ca.activity_type_id, ca.id"; } if (!empty($criteriaParams['newest'])) { diff --git a/CRM/Contact/BAO/Contact/Utils.php b/CRM/Contact/BAO/Contact/Utils.php index 4a94e0c5dad7..3339de232ab4 100644 --- a/CRM/Contact/BAO/Contact/Utils.php +++ b/CRM/Contact/BAO/Contact/Utils.php @@ -777,12 +777,13 @@ public static function contactDetails($componentIds, $componentName, $returnProp $fromClause = implode(' ', $from); $selectClause = implode(', ', $select); $whereClause = "{$compTable}.id IN (" . implode(',', $componentIds) . ')'; + $groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($select, array("{$compTable}.id", 'contact.id')); $query = " SELECT contact.id as contactId, $compTable.id as componentId, $selectClause FROM $compTable as $compTable $fromClause WHERE $whereClause -Group By componentId"; + {$groupBy}"; $contact = CRM_Core_DAO::executeQuery($query); while ($contact->fetch()) { diff --git a/CRM/Contact/BAO/Group.php b/CRM/Contact/BAO/Group.php index df0ae58ae881..2a5b7e04a62a 100644 --- a/CRM/Contact/BAO/Group.php +++ b/CRM/Contact/BAO/Group.php @@ -854,7 +854,6 @@ public static function getGroupList(&$params) { ON createdBy.id = groups.created_id {$from} WHERE $whereClause {$where} - GROUP BY groups.id {$orderBy} {$limit}"; diff --git a/CRM/Contact/BAO/GroupContact.php b/CRM/Contact/BAO/GroupContact.php index 78722e001bd9..444ab8bb7324 100644 --- a/CRM/Contact/BAO/GroupContact.php +++ b/CRM/Contact/BAO/GroupContact.php @@ -280,7 +280,7 @@ public static function getGroupList($contactId = 0, $visibility = FALSE) { $select = $from = $where = ''; - $select = 'SELECT DISTINCT civicrm_group.id, civicrm_group.title '; + $select = 'SELECT civicrm_group.id, civicrm_group.title '; $from = ' FROM civicrm_group '; $where = " WHERE civicrm_group.is_active = 1 "; if ($contactId) { @@ -292,9 +292,10 @@ public static function getGroupList($contactId = 0, $visibility = FALSE) { if ($visibility) { $where .= " AND civicrm_group.visibility != 'User and User Admin Only'"; } + $groupBy = " GROUP BY civicrm_group.id"; $orderby = " ORDER BY civicrm_group.name"; - $sql = $select . $from . $where . $orderby; + $sql = $select . $from . $where . $groupBy . $orderby; $group->query($sql); diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 8eb6257ddfbf..ec4b004e1588 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -4334,7 +4334,7 @@ public static function apiQuery( // add group by if ($query->_useGroupBy) { - $sql .= ' GROUP BY contact_a.id'; + $sql .= self::getGroupByFromSelectColumns($query->_select, 'contact_a.id'); } if (!empty($sort)) { $sort = CRM_Utils_Type::escape($sort, 'String'); @@ -4520,6 +4520,59 @@ public static function filterCountryFromValuesIfStateExists(&$formValues) { } } + /** + * Include Select columns in groupBy clause. + * + * @param array $selectClauses + * @param array $groupBy - Columns already included in GROUP By clause. + * + * @return string + */ + public static function getGroupByFromSelectColumns($selectClauses, $groupBy = NULL) { + $groupBy = (array) $groupBy; + $mysqlVersion = CRM_Core_DAO::singleValueQuery('SELECT VERSION()'); + $sqlMode = CRM_Core_DAO::singleValueQuery('SELECT @@sql_mode'); + + //return if ONLY_FULL_GROUP_BY is not enabled. + if (!version_compare($mysqlVersion, '5.7', '<') && !empty($sqlMode) && in_array('ONLY_FULL_GROUP_BY', explode(',', $sqlMode))) { + $regexToExclude = '/(ROUND|AVG|COUNT|GROUP_CONCAT|SUM|MAX|MIN)\(/i'; + foreach ($selectClauses as $key => $val) { + $aliasArray = preg_split('/ as /i', $val); + // if more than 1 alias we need to split by ','. + if (count($aliasArray) > 2) { + $aliasArray = preg_split('/,/', $val); + foreach ($aliasArray as $key => $value) { + $alias = current(preg_split('/ as /i', $value)); + if (!in_array($alias, $groupBy) && preg_match($regexToExclude, trim($alias)) !== 1) { + $groupBy[] = $alias; + } + } + } + else { + list($selectColumn, $alias) = array_pad($aliasArray, 2, NULL); + $dateRegex = '/^(DATE_FORMAT|DATE_ADD|CASE)/i'; + $tableName = current(explode('.', $selectColumn)); + $primaryKey = "{$tableName}.id"; + // exclude columns which are already included in groupBy and aggregate functions from select + // CRM-18439 - Also exclude the columns which are functionally dependent on columns in $groupBy (MySQL 5.7+) + if (!in_array($selectColumn, $groupBy) && !in_array($primaryKey, $groupBy) && preg_match($regexToExclude, trim($selectColumn)) !== 1) { + if (!empty($alias) && preg_match($dateRegex, trim($selectColumn))) { + $groupBy[] = $alias; + } + else { + $groupBy[] = $selectColumn; + } + } + } + } + } + + if (!empty($groupBy)) { + return " GROUP BY " . implode(', ', $groupBy); + } + return ''; + } + /** * Create and query the db for an contact search. * @@ -4580,16 +4633,20 @@ public function searchQuery( } // building the query string - $groupBy = NULL; + $groupBy = $groupByCol = NULL; if (!$count) { if (isset($this->_groupByComponentClause)) { $groupBy = $this->_groupByComponentClause; + $groupCols = preg_replace('/^GROUP BY /', '', trim($this->_groupByComponentClause)); + $groupByCol = explode(', ', $groupCols); } elseif ($this->_useGroupBy) { + $groupByCol = 'contact_a.id'; $groupBy = ' GROUP BY contact_a.id'; } } if ($this->_mode & CRM_Contact_BAO_Query::MODE_ACTIVITY && (!$count)) { + $groupByCol = 'civicrm_activity.id'; $groupBy = 'GROUP BY civicrm_activity.id '; } @@ -4612,6 +4669,10 @@ public function searchQuery( list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts, $onlyDeleted); + if (!empty($groupByCol)) { + $groupBy = self::getGroupByFromSelectColumns($this->_select, $groupByCol); + } + if ($additionalWhereClause) { $where = $where . ' AND ' . $additionalWhereClause; } @@ -4669,7 +4730,8 @@ public function getCachedContacts($cacheKey, $offset, $rowCount, $includeContact list($select, $from, $where) = $this->query(FALSE, FALSE, FALSE, $onlyDeleted); $from = " FROM civicrm_prevnext_cache pnc INNER JOIN civicrm_contact contact_a ON contact_a.id = pnc.entity_id1 AND pnc.cacheKey = '$cacheKey' " . substr($from, 31); $order = " ORDER BY pnc.id"; - $groupBy = " GROUP BY contact_a.id"; + $groupByCol = array('contact_a.id', 'pnc.id'); + $groupBy = self::getGroupByFromSelectColumns($this->_select, $groupByCol); $limit = " LIMIT $offset, $rowCount"; $query = "$select $from $where $groupBy $order $limit"; @@ -4749,7 +4811,6 @@ public function &summaryContribution($context = NULL) { SELECT COUNT( conts.total_amount ) as total_count, SUM( conts.total_amount ) as total_amount, AVG( conts.total_amount ) as total_avg, - conts.total_amount as amount, conts.currency as currency"; if ($this->_permissionWhereClause) { $where .= " AND " . $this->_permissionWhereClause; @@ -4793,9 +4854,12 @@ public function &summaryContribution($context = NULL) { $orderBy = 'ORDER BY civicrm_contribution_total_amount_count DESC'; $groupBy = 'GROUP BY currency, civicrm_contribution.total_amount'; - $modeSQL = "$select, conts.civicrm_contribution_total_amount_count as civicrm_contribution_total_amount_count FROM ($innerQuery - $groupBy $orderBy) as conts - GROUP BY currency"; + $modeSQL = "$select, SUBSTRING_INDEX(GROUP_CONCAT(conts.total_amount + ORDER BY conts.civicrm_contribution_total_amount_count DESC SEPARATOR ';'), ';', 1) as amount, + MAX(conts.civicrm_contribution_total_amount_count) as civicrm_contribution_total_amount_count + FROM ($innerQuery + $groupBy $orderBy) as conts + GROUP BY currency"; $summary['total']['mode'] = CRM_Contribute_BAO_Contribution::computeStats('mode', $modeSQL); diff --git a/CRM/Contact/Form/Search/Custom/EventAggregate.php b/CRM/Contact/Form/Search/Custom/EventAggregate.php index 199f93564f77..e2bb5aa3b76d 100644 --- a/CRM/Contact/Form/Search/Custom/EventAggregate.php +++ b/CRM/Contact/Form/Search/Custom/EventAggregate.php @@ -159,10 +159,11 @@ public function all( } $where = $this->where(); + $groupFromSelect = "civicrm_option_value.label, civicrm_contribution.payment_instrument_id"; - $groupBy = "event_id"; + $groupBy = "event_id, event_type_id, {$groupFromSelect}"; if (!empty($this->_formValues['event_type_id'])) { - $groupBy = "event_type_id"; + $groupBy = "event_type_id, event_id, {$groupFromSelect}"; } $sql = " diff --git a/CRM/Contact/Form/Search/Custom/FullText/Activity.php b/CRM/Contact/Form/Search/Custom/FullText/Activity.php index 2e30090b5172..e839c0521bd9 100644 --- a/CRM/Contact/Form/Search/Custom/FullText/Activity.php +++ b/CRM/Contact/Form/Search/Custom/FullText/Activity.php @@ -148,7 +148,6 @@ public function moveIDs($fromTable, $toTable, $limit) { LEFT JOIN civicrm_case_activity cca ON cca.activity_id = ca.id LEFT JOIN civicrm_case_contact ccc ON ccc.case_id = cca.case_id WHERE (ca.is_deleted = 0 OR ca.is_deleted IS NULL) -GROUP BY ca.id {$this->toLimit($limit)} "; CRM_Core_DAO::executeQuery($sql); diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 0f54881f0be4..a04b72a3bcb8 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4005,6 +4005,7 @@ public static function getPaymentInfo($id, $component, $getTrxnInfo = FALSE, $us if ($getTrxnInfo && $baseTrxnId) { $arRelationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $arAccount = CRM_Contribute_PseudoConstant::financialAccountType($financialTypeId, $arRelationTypeId); + // Need to exclude fee trxn rows so filter out rows where TO FINANCIAL ACCOUNT is expense account $sql = " SELECT GROUP_CONCAT(fa.`name`) as financial_account, @@ -4021,8 +4022,8 @@ public static function getPaymentInfo($id, $component, $getTrxnInfo = FALSE, $us INNER JOIN civicrm_financial_account fa ON fa.id = fi.financial_account_id WHERE con.id = %1 AND ft.to_financial_account_id <> %3 - GROUP BY ft.id - "; + GROUP BY ft.id"; + $queryParams = array( 1 => array($contributionId, 'Integer'), 2 => array($feeFinancialAccount, 'Integer'), diff --git a/CRM/Contribute/BAO/Query.php b/CRM/Contribute/BAO/Query.php index eb0314e60ef9..60769cedc870 100644 --- a/CRM/Contribute/BAO/Query.php +++ b/CRM/Contribute/BAO/Query.php @@ -825,7 +825,7 @@ public static function isSoftCreditOptionEnabled($queryParams = array()) { SELECT con.id as id, con.contact_id, cso.id as filter_id, NULL as scredit_id FROM civicrm_contribution con LEFT JOIN civicrm_contribution_soft cso ON con.id = cso.contribution_id - GROUP BY id, contact_id, scredit_id + GROUP BY id, contact_id, scredit_id, cso.id UNION ALL SELECT scredit.contribution_id as id, scredit.contact_id, scredit.id as filter_id, scredit.id as scredit_id FROM civicrm_contribution_soft as scredit"; diff --git a/CRM/Contribute/Page/ContributionPage.php b/CRM/Contribute/Page/ContributionPage.php index bfc2e236fb39..b219846ceda3 100644 --- a/CRM/Contribute/Page/ContributionPage.php +++ b/CRM/Contribute/Page/ContributionPage.php @@ -675,7 +675,7 @@ public function pagerAtoZ($whereClause, $whereParams) { SELECT DISTINCT UPPER(LEFT(title, 1)) as sort_name FROM civicrm_contribution_page WHERE $whereClause -ORDER BY LEFT(title, 1) +ORDER BY UPPER(LEFT(title, 1)) "; $dao = CRM_Core_DAO::executeQuery($query, $whereParams); diff --git a/CRM/Event/BAO/Event.php b/CRM/Event/BAO/Event.php index d5419f8458eb..a68f2305e4d0 100644 --- a/CRM/Event/BAO/Event.php +++ b/CRM/Event/BAO/Event.php @@ -416,7 +416,6 @@ public static function getEventSummary() { ( civicrm_event.is_template IS NULL OR civicrm_event.is_template = 0) AND civicrm_event.start_date >= DATE_SUB( NOW(), INTERVAL 7 day ) $validEventIDs -GROUP BY civicrm_event.id ORDER BY civicrm_event.start_date ASC $event_summary_limit "; diff --git a/CRM/Event/BAO/Participant.php b/CRM/Event/BAO/Participant.php index 255b54aed490..49921a411e93 100644 --- a/CRM/Event/BAO/Participant.php +++ b/CRM/Event/BAO/Participant.php @@ -1931,7 +1931,7 @@ public static function changeFeeSelections($params, $participantId, $contributio SELECT fi.*, SUM(fi.amount) as differenceAmt, price_field_value_id, financial_type_id, tax_amount FROM civicrm_financial_item fi LEFT JOIN civicrm_line_item li ON (li.id = fi.entity_id AND fi.entity_table = 'civicrm_line_item') WHERE (li.entity_table = 'civicrm_participant' AND li.entity_id = {$participantId}) -GROUP BY li.entity_table, li.entity_id, price_field_value_id +GROUP BY li.entity_table, li.entity_id, price_field_value_id, fi.id "; $updateFinancialItemInfoDAO = CRM_Core_DAO::executeQuery($updateFinancialItem); $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId, 'DESC', TRUE); diff --git a/CRM/Event/Page/ManageEvent.php b/CRM/Event/Page/ManageEvent.php index ed741659acd2..a661d3ad6b35 100644 --- a/CRM/Event/Page/ManageEvent.php +++ b/CRM/Event/Page/ManageEvent.php @@ -554,7 +554,7 @@ public function pagerAtoZ($whereClause, $whereParams) { SELECT DISTINCT UPPER(LEFT(title, 1)) as sort_name FROM civicrm_event WHERE $whereClause - ORDER BY LEFT(title, 1) + ORDER BY UPPER(LEFT(title, 1)) "; $dao = CRM_Core_DAO::executeQuery($query, $whereParams); diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index 3fd75e4a2933..6077d1a83d59 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -172,37 +172,40 @@ public static function exportComponent($exportMode) { * Group By Clause */ public static function getGroupBy($exportMode, $queryMode, $returnProperties, $query) { + $groupBy = ''; if (!empty($returnProperties['tags']) || !empty($returnProperties['groups']) || CRM_Utils_Array::value('notes', $returnProperties) || // CRM-9552 ($queryMode & CRM_Contact_BAO_Query::MODE_CONTACTS && $query->_useGroupBy) ) { - $groupBy = " GROUP BY contact_a.id"; + $groupBy = "contact_a.id"; } switch ($exportMode) { case CRM_Export_Form_Select::CONTRIBUTE_EXPORT: - $groupBy = 'GROUP BY civicrm_contribution.id'; + $groupBy = 'civicrm_contribution.id'; if (CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled()) { // especial group by when soft credit columns are included - $groupBy = 'GROUP BY contribution_search_scredit_combined.id, contribution_search_scredit_combined.scredit_id'; + $groupBy = array('contribution_search_scredit_combined.id', 'contribution_search_scredit_combined.scredit_id'); } break; case CRM_Export_Form_Select::EVENT_EXPORT: - $groupBy = 'GROUP BY civicrm_participant.id'; + $groupBy = 'civicrm_participant.id'; break; case CRM_Export_Form_Select::MEMBER_EXPORT: - $groupBy = " GROUP BY civicrm_membership.id"; + $groupBy = "civicrm_membership.id"; break; } if ($queryMode & CRM_Contact_BAO_Query::MODE_ACTIVITY) { - $groupBy = " GROUP BY civicrm_activity.id "; + $groupBy = "civicrm_activity.id "; } - $groupBy = !empty($groupBy) ? $groupBy : ''; + if (!empty($groupBy)) { + $groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($query->_select, $groupBy); + } return $groupBy; } diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php index e09c1fe59117..a89bf9d26620 100644 --- a/CRM/Mailing/BAO/Mailing.php +++ b/CRM/Mailing/BAO/Mailing.php @@ -287,7 +287,7 @@ public static function getRecipients( $query = "REPLACE INTO I_$job_id (email_id, contact_id) - SELECT DISTINCT $email.id as email_id, + SELECT $email.id as email_id, $contact.id as contact_id FROM $email INNER JOIN $contact @@ -312,6 +312,7 @@ public static function getRecipients( AND $email.on_hold = 0 AND $mg.mailing_id = {$mailing_id} AND X_$job_id.contact_id IS null + GROUP BY $email.id, $contact.id $order_by"; if ($mode == 'sms') { @@ -348,7 +349,7 @@ public static function getRecipients( // Query prior mailings. $query = "REPLACE INTO I_$job_id (email_id, contact_id) - SELECT DISTINCT $email.id as email_id, + SELECT $email.id as email_id, $contact.id as contact_id FROM $email INNER JOIN $contact @@ -370,6 +371,7 @@ public static function getRecipients( AND $email.on_hold = 0 AND $mg.mailing_id = {$mailing_id} AND X_$job_id.contact_id IS null + GROUP BY $email.id, $contact.id $order_by"; if ($mode == 'sms') { @@ -472,7 +474,7 @@ public static function getRecipients( // Get the emails with only location override. $query = "REPLACE INTO I_$job_id (email_id, contact_id) - SELECT DISTINCT $email.id as local_email_id, + SELECT $email.id as local_email_id, $contact.id as contact_id FROM $email INNER JOIN $contact @@ -494,6 +496,7 @@ public static function getRecipients( AND $email.on_hold = 0 AND $mg.mailing_id = {$mailing_id} AND X_$job_id.contact_id IS null + GROUP BY $email.id, $contact.id $order_by"; if ($mode == "sms") { $query = "REPLACE INTO I_$job_id (phone_id, contact_id) @@ -539,7 +542,7 @@ public static function getRecipients( $groupBy = $groupJoin = ''; if ($dedupeEmail) { $groupJoin = " INNER JOIN civicrm_email e ON e.id = i.email_id"; - $groupBy = " GROUP BY e.email "; + $groupBy = " GROUP BY e.email, i.contact_id "; } $sql = " @@ -2466,7 +2469,7 @@ public static function mailingACLIDs() { $mailings = implode(',', $mailingIDs); $mailingQuery = " SELECT DISTINCT ( m.id ) as id - FROM civicrm_mailing m + FROM civicrm_mailing m LEFT JOIN civicrm_mailing_group g ON g.mailing_id = m.id WHERE g.entity_table like 'civicrm_mailing%' AND g.entity_id IN ($mailings)"; $mailingDao = CRM_Core_DAO::executeQuery($mailingQuery); @@ -2505,31 +2508,31 @@ public function &getRows($offset, $rowCount, $sort, $additionalClause = NULL, $a //get all campaigns. $allCampaigns = CRM_Campaign_BAO_Campaign::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE); + $select = array( + "$mailing.id", "$mailing.name", "$job.status", + "$mailing.approval_status_id", "createdContact.sort_name as created_by", "scheduledContact.sort_name as scheduled_by", + "$mailing.created_id as created_id", "$mailing.scheduled_id as scheduled_id", "$mailing.is_archived as archived", + "$mailing.created_date as created_date", "campaign_id", "$mailing.sms_provider_id as sms_provider_id", + ); // we only care about parent jobs, since that holds all the info on // the mailing + $selectClause = implode(', ', $select); + $groupFromSelect = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($select, "$mailing.id"); $query = " - SELECT $mailing.id, - $mailing.name, - $job.status, - $mailing.approval_status_id, + SELECT {$selectClause}, MIN($job.scheduled_date) as scheduled_date, MIN($job.start_date) as start_date, - MAX($job.end_date) as end_date, - createdContact.sort_name as created_by, - scheduledContact.sort_name as scheduled_by, - $mailing.created_id as created_id, - $mailing.scheduled_id as scheduled_id, - $mailing.is_archived as archived, - $mailing.created_date as created_date, - campaign_id, - $mailing.sms_provider_id as sms_provider_id + MAX($job.end_date) as end_date FROM $mailing LEFT JOIN $job ON ( $job.mailing_id = $mailing.id AND $job.is_test = 0 AND $job.parent_id IS NULL ) LEFT JOIN civicrm_contact createdContact ON ( civicrm_mailing.created_id = createdContact.id ) LEFT JOIN civicrm_contact scheduledContact ON ( civicrm_mailing.scheduled_id = scheduledContact.id ) - WHERE $mailingACL $additionalClause - GROUP BY $mailing.id "; + WHERE $mailingACL $additionalClause"; + + if (!empty($groupFromSelect)) { + $query .= $groupFromSelect; + } if ($sort) { $orderBy = trim($sort->orderBy()); diff --git a/CRM/Mailing/PseudoConstant.php b/CRM/Mailing/PseudoConstant.php index e92e46e869fa..9099a9e321d7 100644 --- a/CRM/Mailing/PseudoConstant.php +++ b/CRM/Mailing/PseudoConstant.php @@ -196,7 +196,7 @@ public static function &defaultComponent($type, $undefined = NULL) { FROM civicrm_mailing_component WHERE is_active = 1 AND is_default = 1 - GROUP BY component_type"; + GROUP BY component_type, id"; $dao = CRM_Core_DAO::executeQuery($queryDefaultComponents); diff --git a/CRM/Mailing/Selector/Browse.php b/CRM/Mailing/Selector/Browse.php index 850db5458df0..9ede064a7566 100644 --- a/CRM/Mailing/Selector/Browse.php +++ b/CRM/Mailing/Selector/Browse.php @@ -598,7 +598,7 @@ public function pagerAtoZ() { LEFT JOIN civicrm_contact createdContact ON ( civicrm_mailing.created_id = createdContact.id ) LEFT JOIN civicrm_contact scheduledContact ON ( civicrm_mailing.scheduled_id = scheduledContact.id ) WHERE $whereClause -ORDER BY LEFT(name, 1) +ORDER BY UPPER(LEFT(name, 1)) "; $dao = CRM_Core_DAO::executeQuery($query, $params); diff --git a/CRM/PCP/BAO/PCP.php b/CRM/PCP/BAO/PCP.php index 417aa279367b..1c1ce614cfd7 100644 --- a/CRM/PCP/BAO/PCP.php +++ b/CRM/PCP/BAO/PCP.php @@ -194,7 +194,7 @@ public static function getPcpDashboardInfo($contactId) { LEFT JOIN civicrm_pcp pcp ON pcp.pcp_block_id = block.id WHERE block.is_active = 1 {$clause} -GROUP BY block.id +GROUP BY block.id, pcp.id ORDER BY target_entity_type, target_entity_id "; $pcpBlockDao = CRM_Core_DAO::executeQuery($query); diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index 0331ddc3ff89..c101e38c6774 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -2642,6 +2642,35 @@ public function buildQuery($applyLimit = TRUE) { return $sql; } + /** + * append select with ANY_VALUE() keyword. + * + * @param array $selectClauses + * @param array $groupBy - Columns already included in GROUP By clause. + */ + public function appendSelect($selectClauses, $groupBy) { + $mysqlVersion = CRM_Core_DAO::singleValueQuery('SELECT VERSION()'); + $sqlMode = explode(',', CRM_Core_DAO::singleValueQuery('SELECT @@sql_mode')); + + // Disable only_full_group_by mode for lower sql versions. + if (version_compare($mysqlVersion, '5.7', '<') || (!empty($sqlMode) && !in_array('ONLY_FULL_GROUP_BY', $sqlMode))) { + $key = array_search('ONLY_FULL_GROUP_BY', $sqlMode); + unset($sqlMode[$key]); + CRM_Core_DAO::executeQuery("SET SESSION sql_mode = '" . implode(',', $sqlMode) . "'"); + return; + } + $groupBy = array_map('trim', (array) $groupBy); + $aggregateFunctions = '/(ROUND|AVG|COUNT|GROUP_CONCAT|SUM|MAX|MIN)\(/i'; + foreach ($selectClauses as $key => &$val) { + list($selectColumn, $alias) = array_pad(preg_split('/ as /i', $val), 2, NULL); + // append ANY_VALUE() keyword + if (!in_array($selectColumn, $groupBy) && preg_match($aggregateFunctions, trim($selectColumn)) !== 1) { + $val = str_replace($selectColumn, "ANY_VALUE({$selectColumn})", $val); + } + } + $this->_select = "SELECT " . implode(', ', $selectClauses) . " "; + } + /** * Build group by clause. */ @@ -2662,7 +2691,7 @@ public function groupBy() { } if (!empty($groupBys)) { - $this->_groupBy = "GROUP BY " . implode(', ', $groupBys); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBys); } } @@ -2814,12 +2843,14 @@ public function sectionTotals() { foreach (array_merge($sectionAliases, $this->_selectAliases) as $alias) { $ifnulls[] = "ifnull($alias, '') as $alias"; } + $this->_select = "SELECT " . implode(", ", $ifnulls); + $this->appendSelect($ifnulls, $sectionAliases); // Group (un-limited) report by all aliases and get counts. This might // be done more efficiently when the contents of $sql are known, ie. by // overriding this method in the report class. - $query = "select " . implode(", ", $ifnulls) . + $query = $this->_select . ", count(*) as ct from ($sql) as subquery group by " . implode(", ", $sectionAliases); @@ -4595,6 +4626,7 @@ public function alterSectionHeaderForDateTime($tempTable, $columnName) { CRM_Core_DAO::executeQuery($tempQuery); $updateQuery = "UPDATE {$tempTable} SET {$columnName}_date = date({$columnName})"; CRM_Core_DAO::executeQuery($updateQuery); + $this->_selectClauses[] = "{$columnName}_date"; $this->_select .= ", {$columnName}_date"; $this->_sections["{$columnName}_date"] = $this->_sections["{$columnName}"]; unset($this->_sections["{$columnName}"]); diff --git a/CRM/Report/Form/Activity.php b/CRM/Report/Form/Activity.php index 24814b235493..a78eda2db290 100644 --- a/CRM/Report/Form/Activity.php +++ b/CRM/Report/Form/Activity.php @@ -646,7 +646,7 @@ public function where($recordType = NULL) { * Override group by function. */ public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_activity']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_activity']}.id"); } /** @@ -831,9 +831,10 @@ public function postProcess() { } } $this->limit(); + $groupByFromSelect = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, 'civicrm_activity_id'); $sql = "{$this->_select} FROM civireport_activity_temp_target tar -GROUP BY civicrm_activity_id {$this->_having} {$this->_orderBy} {$this->_limit}"; +{$groupByFromSelect} {$this->_having} {$this->_orderBy} {$this->_limit}"; $this->buildRows($sql, $rows); // format result set. @@ -1033,8 +1034,10 @@ public function sectionTotals() { foreach (array_merge($sectionAliases, $this->_selectAliases) as $alias) { $ifnulls[] = "ifnull($alias, '') as $alias"; } + $this->_select = "SELECT " . implode(", ", $ifnulls); + $this->appendSelect($ifnulls, $sectionAliases); - $query = "select " . implode(", ", $ifnulls) . + $query = $this->_select . ", count(DISTINCT civicrm_activity_id) as ct from civireport_activity_temp_target group by " . implode(", ", $sectionAliases); diff --git a/CRM/Report/Form/ActivitySummary.php b/CRM/Report/Form/ActivitySummary.php index b25165548d17..43c2169719d6 100644 --- a/CRM/Report/Form/ActivitySummary.php +++ b/CRM/Report/Form/ActivitySummary.php @@ -275,6 +275,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -400,7 +401,7 @@ public function where($durationMode = FALSE) { } } - public function groupBy() { + public function groupBy($includeSelectCol = TRUE) { $this->_groupBy = array(); if (!empty($this->_params['group_bys']) && is_array($this->_params['group_bys'])) { @@ -431,12 +432,16 @@ public function groupBy() { } } } - + $groupBy = $this->_groupBy; $this->_groupBy = "GROUP BY " . implode(', ', $this->_groupBy); } else { + $groupBy = "{$this->_aliases['civicrm_activity']}.id"; $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_activity']}.id "; } + if ($includeSelectCol) { + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); + } } /** @@ -537,6 +542,7 @@ public function postProcess() { // now build the query for duration sum $this->from(TRUE); $this->where(TRUE); + $this->groupBy(FALSE); // build the query to calulate duration sum $sql = "SELECT SUM(activity_civireport.duration) as civicrm_activity_duration_total {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; diff --git a/CRM/Report/Form/Case/Demographics.php b/CRM/Report/Form/Case/Demographics.php index 177d29faf777..3badc118d50f 100644 --- a/CRM/Report/Form/Case/Demographics.php +++ b/CRM/Report/Form/Case/Demographics.php @@ -251,6 +251,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -357,7 +358,8 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id, {$this->_aliases['civicrm_case']}.id"; + $groupBy = array("{$this->_aliases['civicrm_contact']}.id", "{$this->_aliases['civicrm_case']}.id"); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Case/Detail.php b/CRM/Report/Form/Case/Detail.php index c3982af1ea76..1945b903487d 100644 --- a/CRM/Report/Form/Case/Detail.php +++ b/CRM/Report/Form/Case/Detail.php @@ -336,6 +336,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = 'SELECT ' . implode(', ', $select) . ' '; } @@ -451,7 +452,7 @@ public function where() { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_case']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_case']}.id"); } /** diff --git a/CRM/Report/Form/Case/Summary.php b/CRM/Report/Form/Case/Summary.php index a5b625463ba1..ea39d69d3635 100644 --- a/CRM/Report/Form/Case/Summary.php +++ b/CRM/Report/Form/Case/Summary.php @@ -215,6 +215,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } diff --git a/CRM/Report/Form/Case/TimeSpent.php b/CRM/Report/Form/Case/TimeSpent.php index f09b55740194..c90270576470 100644 --- a/CRM/Report/Form/Case/TimeSpent.php +++ b/CRM/Report/Form/Case/TimeSpent.php @@ -208,6 +208,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -284,12 +285,15 @@ public function where() { public function groupBy() { $this->_groupBy = ''; if ($this->has_grouping) { - $this->_groupBy = " -GROUP BY {$this->_aliases['civicrm_contact']}.id, -"; - $this->_groupBy .= ($this->has_activity_type) ? "{$this->_aliases['civicrm_activity']}.activity_type_id, " : ""; - $this->_groupBy .= "civicrm_activity_activity_date_time -"; + $groupBy = array( + "{$this->_aliases['civicrm_contact']}.id", + "civicrm_activity_activity_date_time", + ); + if ($this->has_activity_type) { + $groupBy[] = "{$this->_aliases['civicrm_activity']}.activity_type_id"; + } + + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } } diff --git a/CRM/Report/Form/Contact/CurrentEmployer.php b/CRM/Report/Form/Contact/CurrentEmployer.php index fc85be7a6a1a..150fe68cf8b9 100644 --- a/CRM/Report/Form/Contact/CurrentEmployer.php +++ b/CRM/Report/Form/Contact/CurrentEmployer.php @@ -246,6 +246,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -321,7 +322,12 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_employer']}.id,{$this->_aliases['civicrm_contact']}.id"; + $groupBy = array( + "{$this->_aliases['civicrm_employer']}.id", + "{$this->_aliases['civicrm_contact']}.id", + ); + + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Contact/Detail.php b/CRM/Report/Form/Contact/Detail.php index d8703f8d2516..f738138a08e7 100644 --- a/CRM/Report/Form/Contact/Detail.php +++ b/CRM/Report/Form/Contact/Detail.php @@ -614,8 +614,6 @@ public function where() { if ($this->_aclWhere) { $this->_where .= " AND {$this->_aclWhere} "; } - - $this->_where .= " GROUP BY {$this->_aliases['civicrm_contact']}.id "; } /** @@ -631,7 +629,7 @@ public function clauseComponent() { ) { $sql = "{$this->_selectComponent[$val]} {$this->_formComponent[$val]} WHERE {$this->_aliases['civicrm_contact']}.id IN ( $selectedContacts ) - GROUP BY {$this->_aliases['civicrm_contact']}.id,{$val}.id "; + "; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { @@ -667,7 +665,7 @@ public function clauseComponent() { {$this->_aliases['civicrm_relationship']}.is_active = 1 AND contact_a.is_deleted = 0 AND {$this->_aliases['civicrm_contact']}.is_deleted = 0 - GROUP BY {$this->_aliases['civicrm_relationship']}.id"; + "; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { @@ -724,9 +722,6 @@ public function clauseComponent() { civicrm_option_group.name = 'activity_type' AND {$this->_aliases['civicrm_activity']}.is_test = 0 AND ($componentClause) - - GROUP BY {$this->_aliases['civicrm_activity']}.id - ORDER BY {$this->_aliases['civicrm_activity']}.activity_date_time desc "; $dao = CRM_Core_DAO::executeQuery($sql); diff --git a/CRM/Report/Form/Contact/Relationship.php b/CRM/Report/Form/Contact/Relationship.php index 36e3d06d9996..0b44dffd90cd 100644 --- a/CRM/Report/Form/Contact/Relationship.php +++ b/CRM/Report/Form/Contact/Relationship.php @@ -321,6 +321,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -559,12 +560,13 @@ public function groupBy() { } if (!empty($groupBy)) { - $this->_groupBy = " GROUP BY " . implode(', ', $groupBy) . - " , {$this->_aliases['civicrm_relationship']}.id "; + $groupBy[] = "{$this->_aliases['civicrm_relationship']}.id"; } else { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_relationship']}.id "; + $groupBy = array("{$this->_aliases['civicrm_relationship']}.id"); } + + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Contribute/Bookkeeping.php b/CRM/Report/Form/Contribute/Bookkeeping.php index f71433d68983..1f818f4f74e4 100644 --- a/CRM/Report/Form/Contribute/Bookkeeping.php +++ b/CRM/Report/Form/Contribute/Bookkeeping.php @@ -397,6 +397,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = 'SELECT ' . implode(', ', $select) . ' '; } @@ -432,7 +433,7 @@ public function from() { ON fitem.entity_id = {$this->_aliases['civicrm_line_item']}.id AND fitem.entity_table = 'civicrm_line_item' "; if ($this->isTableSelected('civicrm_batch')) { $this->_from .= "LEFT JOIN civicrm_entity_batch ent_batch - ON {$this->_aliases['civicrm_financial_trxn']}.id = ent_batch.entity_id AND ent_batch.entity_table = 'civicrm_financial_trxn' + ON {$this->_aliases['civicrm_financial_trxn']}.id = ent_batch.entity_id AND ent_batch.entity_table = 'civicrm_financial_trxn' LEFT JOIN civicrm_batch batch ON ent_batch.batch_id = batch.id"; } @@ -512,7 +513,11 @@ public function postProcess() { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_entity_financial_trxn']}.id, {$this->_aliases['civicrm_line_item']}.id "; + $groupBy = array( + "{$this->_aliases['civicrm_entity_financial_trxn']}.id", + "{$this->_aliases['civicrm_line_item']}.id", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } /** @@ -523,13 +528,20 @@ public function groupBy() { public function statistics(&$rows) { $statistics = parent::statistics($rows); $tempTableName = CRM_Core_DAO::createTempTableName('civicrm_contribution'); - $select = "SELECT {$this->_aliases['civicrm_contribution']}.id, {$this->_aliases['civicrm_entity_financial_trxn']}.id as trxnID, {$this->_aliases['civicrm_contribution']}.currency, - CASE - WHEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.entity_id IS NOT NULL - THEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.amount - ELSE {$this->_aliases['civicrm_entity_financial_trxn']}.amount - END as amount -"; + $financialSelect = "CASE WHEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.entity_id IS NOT NULL + THEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.amount + ELSE {$this->_aliases['civicrm_entity_financial_trxn']}.amount + END as amount"; + + $this->_selectClauses = array( + "{$this->_aliases['civicrm_contribution']}.id", + "{$this->_aliases['civicrm_entity_financial_trxn']}.id as trxnID", + "{$this->_aliases['civicrm_contribution']}.currency", + $financialSelect, + ); + $select = "SELECT " . implode(', ', $this->_selectClauses); + + $this->groupBy(); $tempQuery = "CREATE TEMPORARY TABLE {$tempTableName} CHARACTER SET utf8 COLLATE utf8_unicode_ci AS {$select} {$this->_from} {$this->_where} {$this->_groupBy} "; diff --git a/CRM/Report/Form/Contribute/Detail.php b/CRM/Report/Form/Contribute/Detail.php index 1a7c9ac065ce..a5f00c288a85 100644 --- a/CRM/Report/Form/Contribute/Detail.php +++ b/CRM/Report/Form/Contribute/Detail.php @@ -357,6 +357,7 @@ public function select() { //total_amount was affected by sum as it is considered as one of the stat field //so it is been replaced with correct alias, CRM-13833 $this->_select = str_replace("sum({$this->_aliases['civicrm_contribution']}.total_amount)", "{$this->_aliases['civicrm_contribution']}.total_amount", $this->_select); + $this->_selectClauses = str_replace("sum({$this->_aliases['civicrm_contribution']}.total_amount)", "{$this->_aliases['civicrm_contribution']}.total_amount", $this->_selectClauses); } public function orderBy() { @@ -456,7 +457,8 @@ public function from($softcredit = FALSE) { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_contact']}.id, {$this->_aliases['civicrm_contribution']}.id "; + $groupBy = array("{$this->_aliases['civicrm_contact']}.id", "{$this->_aliases['civicrm_contribution']}.id"); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } /** @@ -592,6 +594,9 @@ public function postProcess() { $select = str_ireplace('contribution_civireport.total_amount', 'contribution_soft_civireport.amount', $this->_select); $select = str_ireplace("'Contribution' as", "'Soft Credit' as", $select); + if (!empty($this->_groupBy)) { + $this->_groupBy .= ', contribution_soft_civireport.amount'; + } // we inner join with temp1 to restrict soft contributions to those in temp1 table $sql = "{$select} {$this->_from} {$this->_where} {$this->_groupBy}"; $tempQuery = 'CREATE TEMPORARY TABLE civireport_contribution_detail_temp2 AS ' . $sql; @@ -878,6 +883,8 @@ public function sectionTotals() { foreach (array_merge($sectionAliases, $this->_selectAliases) as $alias) { $ifnulls[] = "ifnull($alias, '') as $alias"; } + $this->_select = "SELECT " . implode(", ", $ifnulls); + $this->appendSelect($ifnulls, $sectionAliases); /* Group (un-limited) report by all aliases and get counts. This might * be done more efficiently when the contents of $sql are known, ie. by @@ -893,9 +900,7 @@ public function sectionTotals() { $showsumcontribs = TRUE; } - $query = "select " - . implode(", ", $ifnulls) - . + $query = $this->_select . "$addtotals, count(*) as ct from civireport_contribution_detail_temp3 group by " . implode(", ", $sectionAliases); // initialize array of total counts diff --git a/CRM/Report/Form/Contribute/History.php b/CRM/Report/Form/Contribute/History.php index 8c3fe86bf7e2..65ad18ea85e4 100644 --- a/CRM/Report/Form/Contribute/History.php +++ b/CRM/Report/Form/Contribute/History.php @@ -366,6 +366,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -479,7 +480,11 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contribution']}.contact_id, YEAR({$this->_aliases['civicrm_contribution']}.receive_date)"; + $groupBy = array( + "{$this->_aliases['civicrm_contribution']}.contact_id", + "YEAR({$this->_aliases['civicrm_contribution']}.receive_date)", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } /** @@ -750,7 +755,7 @@ public function buildRelationshipRows($contactIds) { } $sqlRelationship = "SELECT {$this->_aliases['civicrm_relationship']}.relationship_type_id as relationship_type_id, {$this->_aliases['civicrm_relationship']}.contact_id_a as contact_id_a, {$this->_aliases['civicrm_relationship']}.contact_id_b as contact_id_b {$addRelSelect} FROM civicrm_contact {$relContactAlias} {$this->_relationshipFrom} WHERE {$relContactAlias}.id IN (" . implode(',', $contactIds) . - ") AND {$this->_aliases['civicrm_relationship']}.is_active = 1 {$this->_relationshipWhere} GROUP BY {$this->_aliases['civicrm_relationship']}.contact_id_a, {$this->_aliases['civicrm_relationship']}.contact_id_b"; + ") AND {$this->_aliases['civicrm_relationship']}.is_active = 1 {$this->_relationshipWhere} GROUP BY {$this->_aliases['civicrm_relationship']}.contact_id_a, {$this->_aliases['civicrm_relationship']}.contact_id_b, {$this->_aliases['civicrm_relationship']}.relationship_type_id"; $relationshipTypes = CRM_Core_PseudoConstant::relationshipType(); $dao = CRM_Core_DAO::executeQuery($sqlRelationship); diff --git a/CRM/Report/Form/Contribute/HouseholdSummary.php b/CRM/Report/Form/Contribute/HouseholdSummary.php index dc6954062a17..0c0b7f9654fd 100644 --- a/CRM/Report/Form/Contribute/HouseholdSummary.php +++ b/CRM/Report/Form/Contribute/HouseholdSummary.php @@ -238,6 +238,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -318,7 +319,13 @@ public function where() { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_relationship']}.$this->householdContact, {$this->_aliases['civicrm_relationship']}.$this->otherContact , {$this->_aliases['civicrm_contribution']}.id, {$this->_aliases['civicrm_relationship']}.relationship_type_id "; + $groupBy = array( + "{$this->_aliases['civicrm_relationship']}.$this->householdContact", + "{$this->_aliases['civicrm_relationship']}.$this->otherContact", + "{$this->_aliases['civicrm_contribution']}.id", + "{$this->_aliases['civicrm_relationship']}.relationship_type_id", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Contribute/Lybunt.php b/CRM/Report/Form/Contribute/Lybunt.php index c12deb627c5b..db26b325a90d 100644 --- a/CRM/Report/Form/Contribute/Lybunt.php +++ b/CRM/Report/Form/Contribute/Lybunt.php @@ -550,6 +550,7 @@ public function getLastDateOfPriorRange() { public function groupBy() { $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contribution']}.contact_id "; + $this->appendSelect($this->_selectClauses, "{$this->_aliases['civicrm_contribution']}.contact_id"); $this->assign('chartSupported', TRUE); } @@ -686,7 +687,7 @@ public function buildQuery($applyLimit = TRUE) { $this->limit(); } - $sql = "{$this->_select} {$this->_from} {$this->_where} $limitFilter {$this->_groupBy} {$this->_having} {$this->_rollup}"; + $sql = "{$this->_select} {$this->_from} {$this->_where} {$limitFilter} {$this->_groupBy} {$this->_having} {$this->_rollup}"; if (!empty($this->_orderByArray)) { $this->_orderBy = str_replace('contact_civireport.', 'civicrm_contact_', "ORDER BY ISNULL(civicrm_contribution_contact_id), " . implode(', ', $this->_orderByArray)); diff --git a/CRM/Report/Form/Contribute/OrganizationSummary.php b/CRM/Report/Form/Contribute/OrganizationSummary.php index cc8b2cc9c0a9..0116c5a54ec2 100644 --- a/CRM/Report/Form/Contribute/OrganizationSummary.php +++ b/CRM/Report/Form/Contribute/OrganizationSummary.php @@ -247,6 +247,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -328,7 +329,13 @@ public function where() { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_relationship']}.$this->orgContact, {$this->_aliases['civicrm_relationship']}.$this->otherContact , {$this->_aliases['civicrm_contribution']}.id, {$this->_aliases['civicrm_relationship']}.relationship_type_id "; + $groupBy = array( + "{$this->_aliases['civicrm_relationship']}.$this->orgContact", + "{$this->_aliases['civicrm_relationship']}.$this->otherContact", + "{$this->_aliases['civicrm_contribution']}.id", + "{$this->_aliases['civicrm_relationship']}.relationship_type_id", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Contribute/PCP.php b/CRM/Report/Form/Contribute/PCP.php index 5ef011714df1..52074d09e174 100644 --- a/CRM/Report/Form/Contribute/PCP.php +++ b/CRM/Report/Form/Contribute/PCP.php @@ -193,7 +193,7 @@ public function from() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_pcp']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_pcp']}.id"); } public function orderBy() { diff --git a/CRM/Report/Form/Contribute/Recur.php b/CRM/Report/Form/Contribute/Recur.php index 7675191d99c5..9e5ff3ccec5f 100644 --- a/CRM/Report/Form/Contribute/Recur.php +++ b/CRM/Report/Form/Contribute/Recur.php @@ -253,7 +253,7 @@ public function from() { } public function groupBy() { - $this->_groupBy = "GROUP BY " . $this->_aliases['civicrm_contribution_recur'] . ".id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_contribution_recur']}.id"); } public function where() { diff --git a/CRM/Report/Form/Contribute/RecurSummary.php b/CRM/Report/Form/Contribute/RecurSummary.php index c0353e24f530..8cf5991c412d 100644 --- a/CRM/Report/Form/Contribute/RecurSummary.php +++ b/CRM/Report/Form/Contribute/RecurSummary.php @@ -193,6 +193,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -223,7 +224,7 @@ public function postProcess() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contribution_recur']}.payment_instrument_id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_contribution_recur']}.payment_instrument_id"); } /** @@ -301,9 +302,9 @@ public function alterDisplay(&$rows) { $lineTotal = 0; $amountSql = " - SELECT SUM(cc.total_amount) as amount FROM `civicrm_contribution` cc - INNER JOIN civicrm_contribution_recur cr ON (cr.id = cc.contribution_recur_id AND cr.payment_instrument_id = {$paymentInstrumentId}) - WHERE cc.contribution_status_id = 1 AND cc.is_test = 0 AND "; + SELECT SUM(cc.total_amount) as amount FROM `civicrm_contribution` cc + INNER JOIN civicrm_contribution_recur cr ON (cr.id = cc.contribution_recur_id AND cr.payment_instrument_id = {$paymentInstrumentId}) + WHERE cc.contribution_status_id = 1 AND cc.is_test = 0 AND "; $amountSql .= str_replace("start_date", "cc.`receive_date`", $startedDateSql); $amountDao = CRM_Core_DAO::executeQuery($amountSql); $amountDao->fetch(); diff --git a/CRM/Report/Form/Contribute/Repeat.php b/CRM/Report/Form/Contribute/Repeat.php index 152775c1a473..ae608b46bbab 100644 --- a/CRM/Report/Form/Contribute/Repeat.php +++ b/CRM/Report/Form/Contribute/Repeat.php @@ -320,7 +320,7 @@ public function select() { } } } - + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -1014,7 +1014,7 @@ protected function buildTempTables() { currency {$from} {$subWhere} -GROUP BY contribution2.{$this->contributionJoinTableColumn}"; +GROUP BY contribution2.{$this->contributionJoinTableColumn}, currency"; $this->tempTableRepeat1 = 'civicrm_temp_civireport_repeat1' . uniqid(); $sql = " CREATE TEMPORARY TABLE $this->tempTableRepeat1 ( diff --git a/CRM/Report/Form/Contribute/SoftCredit.php b/CRM/Report/Form/Contribute/SoftCredit.php index c9058223e750..70b99eb31349 100644 --- a/CRM/Report/Form/Contribute/SoftCredit.php +++ b/CRM/Report/Form/Contribute/SoftCredit.php @@ -380,6 +380,7 @@ public function select() { } } } + $this->selectClause = $select; $this->_select = 'SELECT ' . implode(', ', $select) . ' '; } @@ -458,6 +459,7 @@ public function from() { public function groupBy() { $this->_rollup = 'WITH ROLLUP'; + $this->appendSelect($this->selectClause, array("{$this->_aliases['civicrm_contribution_soft']}.contact_id", "constituentname.id")); $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_contribution_soft']}.contact_id, constituentname.id {$this->_rollup}"; } diff --git a/CRM/Report/Form/Contribute/Summary.php b/CRM/Report/Form/Contribute/Summary.php index 5c2f76cd18ca..83564ec98718 100644 --- a/CRM/Report/Form/Contribute/Summary.php +++ b/CRM/Report/Form/Contribute/Summary.php @@ -399,6 +399,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -508,7 +509,7 @@ public function groupBy() { !empty($this->_params['group_bys_freq'][$fieldName]) ) { - $append = "YEAR({$field['dbAlias']}),"; + $append = "YEAR({$field['dbAlias']});;"; if (in_array(strtolower($this->_params['group_bys_freq'][$fieldName]), array('year') )) { @@ -536,12 +537,24 @@ public function groupBy() { ) { $this->_rollup = " WITH ROLLUP"; } - $this->_groupBy = "GROUP BY " . implode(', ', $this->_groupBy) . - " {$this->_rollup} "; + $groupBy = array(); + foreach ($this->_groupBy as $key => $val) { + if (strpos($val, ';;') !== FALSE) { + $groupBy = array_merge($groupBy, explode(';;', $val)); + } + else { + $groupBy[] = $this->_groupBy[$key]; + } + } + $this->_groupBy = "GROUP BY " . implode(', ', $groupBy); } else { + $groupBy = "{$this->_aliases['civicrm_contact']}.id"; $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id"; } + $this->_groupBy .= $this->_rollup; + // append select with ANY_VALUE() keyword + $this->appendSelect($this->_selectClauses, $groupBy); } /** @@ -610,8 +623,10 @@ public function statistics(&$rows) { $groupBy = "\n{$group}, {$this->_aliases['civicrm_contribution']}.total_amount"; $orderBy = "\nORDER BY civicrm_contribution_total_amount_count DESC"; - $modeSQL = "SELECT civicrm_contribution_total_amount_count, amount, currency - FROM (SELECT {$this->_aliases['civicrm_contribution']}.total_amount as amount, + $modeSQL = "SELECT MAX(civicrm_contribution_total_amount_count) as civicrm_contribution_total_amount_count, + SUBSTRING_INDEX(GROUP_CONCAT(amount ORDER BY mode.civicrm_contribution_total_amount_count DESC SEPARATOR ';'), ';', 1) as amount, + currency + FROM (SELECT {$this->_aliases['civicrm_contribution']}.total_amount as amount, {$contriQuery} {$groupBy} {$orderBy}) as mode GROUP BY currency"; $mode = CRM_Contribute_BAO_Contribution::computeStats('mode', $modeSQL); diff --git a/CRM/Report/Form/Contribute/Sybunt.php b/CRM/Report/Form/Contribute/Sybunt.php index 3d6655df1534..daf36b1e5729 100644 --- a/CRM/Report/Form/Contribute/Sybunt.php +++ b/CRM/Report/Form/Contribute/Sybunt.php @@ -311,6 +311,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -395,9 +396,10 @@ public function where() { public function groupBy() { $this->assign('chartSupported', TRUE); - $this->_groupBy = "Group BY {$this->_aliases['civicrm_contribution']}.contact_id, " . - self::fiscalYearOffset($this->_aliases['civicrm_contribution'] . - '.receive_date') . " " . " " . $this->_rollup; + $fiscalYearOffset = self::fiscalYearOffset("{$this->_aliases['civicrm_contribution']}.receive_date"); + $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contribution']}.contact_id, {$fiscalYearOffset}"; + $this->appendSelect($this->_selectClauses, array("{$this->_aliases['civicrm_contribution']}.contact_id", $fiscalYearOffset)); + $this->_groupBy .= " {$this->_rollup}"; } /** diff --git a/CRM/Report/Form/Contribute/TopDonor.php b/CRM/Report/Form/Contribute/TopDonor.php index 1ffe5d6115ad..3e71627dc1a7 100644 --- a/CRM/Report/Form/Contribute/TopDonor.php +++ b/CRM/Report/Form/Contribute/TopDonor.php @@ -275,6 +275,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = " SELECT * FROM ( SELECT " . implode(', ', $select) . " "; } @@ -374,7 +375,7 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id, {$this->_aliases['civicrm_contribution']}.currency"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, array("{$this->_aliases['civicrm_contact']}.id", "{$this->_aliases['civicrm_contribution']}.currency")); } public function postProcess() { diff --git a/CRM/Report/Form/Event/Income.php b/CRM/Report/Form/Event/Income.php index d5570f3321c2..6dabed59aca0 100644 --- a/CRM/Report/Form/Event/Income.php +++ b/CRM/Report/Form/Event/Income.php @@ -99,15 +99,19 @@ public function buildEventReport($eventIDs) { $activeParticipantStatus = implode(',', $activeParticipantStatusIDArray); $activeparticipnatStutusLabel = implode(', ', $activeParticipantStatusLabelArray); $activeParticipantClause = " AND civicrm_participant.status_id IN ( $activeParticipantStatus ) "; + $select = array( + "civicrm_event.id as event_id", + "civicrm_event.title as event_title", + "civicrm_event.max_participants as max_participants", + "civicrm_event.start_date as start_date", + "civicrm_event.end_date as end_date", + "civicrm_option_value.label as event_type", + "civicrm_participant.fee_currency as currency", + ); + $groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($select); $sql = " - SELECT civicrm_event.id as event_id, - civicrm_event.title as event_title, - civicrm_event.max_participants as max_participants, - civicrm_event.start_date as start_date, - civicrm_event.end_date as end_date, - civicrm_option_value.label as event_type, - civicrm_participant.fee_currency as currency, + SELECT " . implode(', ', $select) . ", SUM(civicrm_participant.fee_amount) as total, COUNT(civicrm_participant.id) as participant @@ -118,10 +122,7 @@ public function buildEventReport($eventIDs) { LEFT JOIN civicrm_participant ON ( civicrm_event.id = civicrm_participant.event_id {$activeParticipantClause} AND civicrm_participant.is_test = 0 ) - WHERE civicrm_event.id IN( {$eventID}) - - GROUP BY civicrm_event.id - "; + WHERE civicrm_event.id IN( {$eventID}) {$groupBy}"; $eventDAO = CRM_Core_DAO::executeQuery($sql); $currency = array(); @@ -166,7 +167,7 @@ public function buildEventReport($eventIDs) { WHERE civicrm_participant.event_id IN ( {$eventID}) AND civicrm_participant.is_test = 0 {$activeParticipantClause} - GROUP BY civicrm_participant.role_id, civicrm_participant.event_id + GROUP BY civicrm_participant.role_id, civicrm_participant.event_id, civicrm_participant.fee_currency "; $roleDAO = CRM_Core_DAO::executeQuery($role); diff --git a/CRM/Report/Form/Event/IncomeCountSummary.php b/CRM/Report/Form/Event/IncomeCountSummary.php index 8bfd9151ef78..f502c2d0a4bc 100644 --- a/CRM/Report/Form/Event/IncomeCountSummary.php +++ b/CRM/Report/Form/Event/IncomeCountSummary.php @@ -205,6 +205,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select); } @@ -304,7 +305,8 @@ public function statistics(&$rows) { public function groupBy() { $this->assign('chartSupported', TRUE); $this->_rollup = " WITH ROLLUP"; - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_event']}.id {$this->_rollup}"; + $this->appendSelect($this->_selectClauses, "{$this->_aliases['civicrm_event']}.id"); + $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_event']}.id {$this->_rollup}"; } public function postProcess() { diff --git a/CRM/Report/Form/Event/ParticipantListCount.php b/CRM/Report/Form/Event/ParticipantListCount.php index 390e50a66c1c..bc95ee0b41aa 100644 --- a/CRM/Report/Form/Event/ParticipantListCount.php +++ b/CRM/Report/Form/Event/ParticipantListCount.php @@ -425,6 +425,7 @@ public function select() { $this->_columnHeaders["blank_{$i}"]['title'] = "_ _ _ _"; } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -474,7 +475,7 @@ public function groupBy() { // user doesn't select a column to group by, we should group by participant id. parent::groupBy(); if (empty($this->_groupBy)) { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_participant']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_participant']}.id"); } } diff --git a/CRM/Report/Form/Event/ParticipantListing.php b/CRM/Report/Form/Event/ParticipantListing.php index 3497a4a84d06..26713874975d 100644 --- a/CRM/Report/Form/Event/ParticipantListing.php +++ b/CRM/Report/Form/Event/ParticipantListing.php @@ -500,6 +500,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -628,7 +629,7 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_participant']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_participant']}.id"); } public function postProcess() { diff --git a/CRM/Report/Form/Event/Summary.php b/CRM/Report/Form/Event/Summary.php index 291194df896c..17ee01029e8f 100644 --- a/CRM/Report/Form/Event/Summary.php +++ b/CRM/Report/Form/Event/Summary.php @@ -128,6 +128,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = 'SELECT ' . implode(', ', $select); } @@ -179,7 +180,7 @@ public function where() { public function groupBy() { $this->assign('chartSupported', TRUE); - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_event']}.id"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_event']}.id"); } /** @@ -204,7 +205,8 @@ public function participantInfo() { $this->_participantWhere GROUP BY civicrm_participant.event_id, - civicrm_participant.status_id"; + civicrm_participant.status_id, + civicrm_participant.fee_currency"; $info = CRM_Core_DAO::executeQuery($sql); $participant_data = $participant_info = $currency = array(); diff --git a/CRM/Report/Form/Grant/Statistics.php b/CRM/Report/Form/Grant/Statistics.php index 811ee3b113c3..421a8781ef1f 100644 --- a/CRM/Report/Form/Grant/Statistics.php +++ b/CRM/Report/Form/Grant/Statistics.php @@ -234,6 +234,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -318,14 +319,14 @@ public function groupBy() { if (array_key_exists('fields', $table)) { foreach ($table['fields'] as $fieldName => $field) { if (!empty($this->_params['fields'][$fieldName])) { - $this->_groupBy[] = $field['dbAlias']; + $groupBy[] = $field['dbAlias']; } } } } } - if (!empty($this->_groupBy)) { - $this->_groupBy = " GROUP BY " . implode(', ', $this->_groupBy); + if (!empty($groupBy)) { + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } } diff --git a/CRM/Report/Form/Mailing/Bounce.php b/CRM/Report/Form/Mailing/Bounce.php index 82e1b0a6ac58..c994faa1eeb4 100644 --- a/CRM/Report/Form/Mailing/Bounce.php +++ b/CRM/Report/Form/Mailing/Bounce.php @@ -268,6 +268,7 @@ public function select() { $this->_columnHeaders["civicrm_mailing_bounce_count"]['title'] = ts('Bounce Count'); } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -358,11 +359,12 @@ public function where() { public function groupBy() { if (!empty($this->_params['charts'])) { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing']}.id"; + $groupBy = "{$this->_aliases['civicrm_mailing']}.id"; } else { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing_event_bounce']}.id"; + $groupBy = "{$this->_aliases['civicrm_mailing_event_bounce']}.id"; } + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function postProcess() { diff --git a/CRM/Report/Form/Mailing/Clicks.php b/CRM/Report/Form/Mailing/Clicks.php index 3fd5e8e0e2da..de9b1e207241 100644 --- a/CRM/Report/Form/Mailing/Clicks.php +++ b/CRM/Report/Form/Mailing/Clicks.php @@ -208,6 +208,7 @@ public function select() { $this->_columnHeaders["civicrm_mailing_click_count"]['title'] = ts('Click Count'); } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -256,14 +257,14 @@ public function where() { } public function groupBy() { - $this->_groupBy = ''; if (!empty($this->_params['charts'])) { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing']}.id"; + $groupBy = "{$this->_aliases['civicrm_mailing']}.id"; } else { - $this->_groupBy = " GROUP BY civicrm_mailing_event_trackable_url_open.id"; + $groupBy = "civicrm_mailing_event_trackable_url_open.id"; } + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function postProcess() { diff --git a/CRM/Report/Form/Mailing/Opened.php b/CRM/Report/Form/Mailing/Opened.php index 2e70292ee095..3d6649dd4590 100644 --- a/CRM/Report/Form/Mailing/Opened.php +++ b/CRM/Report/Form/Mailing/Opened.php @@ -188,6 +188,7 @@ public function select() { $this->_columnHeaders["civicrm_mailing_opened_count"]['title'] = ts('Opened Count'); } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -236,11 +237,12 @@ public function where() { public function groupBy() { if (!empty($this->_params['charts'])) { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing']}.id"; + $groupBy = "{$this->_aliases['civicrm_mailing']}.id"; } else { - $this->_groupBy = " GROUP BY civicrm_mailing_event_queue.email_id"; + $groupBy = "civicrm_mailing_event_queue.email_id"; } + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function postProcess() { diff --git a/CRM/Report/Form/Mailing/Summary.php b/CRM/Report/Form/Mailing/Summary.php index 2706d4721dd6..2c2a0b798d13 100644 --- a/CRM/Report/Form/Mailing/Summary.php +++ b/CRM/Report/Form/Mailing/Summary.php @@ -362,6 +362,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; //print_r($this->_select); } @@ -391,7 +392,7 @@ public function from() { if ($this->isTableSelected('civicrm_mailing_group')) { $this->_from .= " LEFT JOIN civicrm_mailing_group {$this->_aliases['civicrm_mailing_group']} - ON {$this->_aliases['civicrm_mailing_group']}.mailing_id = {$this->_aliases['civicrm_mailing']}.id"; + ON {$this->_aliases['civicrm_mailing_group']}.mailing_id = {$this->_aliases['civicrm_mailing']}.id"; } if ($this->campaignEnabled) { $this->_from .= " @@ -458,7 +459,11 @@ public function where() { } public function groupBy() { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_mailing']}.id"; + $groupBy = array( + "{$this->_aliases['civicrm_mailing']}.id", + "{$this->_aliases['civicrm_mailing_job']}.end_date", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Member/ContributionDetail.php b/CRM/Report/Form/Member/ContributionDetail.php index 5ecf3266ba5d..b404a55399fb 100644 --- a/CRM/Report/Form/Member/ContributionDetail.php +++ b/CRM/Report/Form/Member/ContributionDetail.php @@ -447,6 +447,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = 'SELECT ' . implode(', ', $select) . ' '; } @@ -589,7 +590,11 @@ public function buildQuery($applyLimit = TRUE) { } public function groupBy() { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_contact']}.id, {$this->_aliases['civicrm_contribution']}.id "; + $groupBy = array( + "{$this->_aliases['civicrm_contact']}.id", + "{$this->_aliases['civicrm_contribution']}.id", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Member/Detail.php b/CRM/Report/Form/Member/Detail.php index cd6ed27ad8a2..fde2da1993de 100644 --- a/CRM/Report/Form/Member/Detail.php +++ b/CRM/Report/Form/Member/Detail.php @@ -288,6 +288,7 @@ public function select() { } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } diff --git a/CRM/Report/Form/Member/Summary.php b/CRM/Report/Form/Member/Summary.php index d5400f5e5664..f7d2f77890d7 100644 --- a/CRM/Report/Form/Member/Summary.php +++ b/CRM/Report/Form/Member/Summary.php @@ -323,6 +323,7 @@ public function select() { unset($select['joinDate']); unset($this->_columnHeaders["civicrm_membership_member_join_date"]); } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -362,13 +363,14 @@ public function groupBy() { !empty($this->_params['group_bys_freq'][$fieldName]) ) { - $append = "YEAR({$field['dbAlias']}),"; + $append = "YEAR({$field['dbAlias']})"; if (in_array(strtolower($this->_params['group_bys_freq'][$fieldName]), array('year') )) { $append = ''; } - $this->_groupBy[] = "$append {$this->_params['group_bys_freq'][$fieldName]}({$field['dbAlias']})"; + $this->_groupBy[] = $append; + $this->_groupBy[] = "{$this->_params['group_bys_freq'][$fieldName]}({$field['dbAlias']})"; $append = TRUE; } else { @@ -380,11 +382,12 @@ public function groupBy() { } $this->_rollup = ' WITH ROLLUP'; - $this->_groupBy = 'GROUP BY ' . implode(', ', $this->_groupBy) . + $this->appendSelect($this->_selectClauses, array_filter($this->_groupBy)); + $this->_groupBy = 'GROUP BY ' . implode(', ', array_filter($this->_groupBy)) . " {$this->_rollup} "; } else { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_membership']}.join_date"; + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_membership']}.join_date"); } } diff --git a/CRM/Report/Form/Pledge/Detail.php b/CRM/Report/Form/Pledge/Detail.php index 3417da4f6d29..b504d1905b03 100644 --- a/CRM/Report/Form/Pledge/Detail.php +++ b/CRM/Report/Form/Pledge/Detail.php @@ -252,7 +252,8 @@ public function selectClause(&$tableName, $tableKey, &$fieldName, &$field) { public function groupBy() { parent::groupBy(); if (empty($this->_groupBy) && $this->_totalPaid) { - $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_pledge']}.id, {$this->_aliases['civicrm_pledge']}.currency"; + $groupBy = array("{$this->_aliases['civicrm_pledge']}.id", "{$this->_aliases['civicrm_pledge']}.currency"); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } } @@ -467,11 +468,10 @@ public function postProcess() { if (!empty($display)) { $statusId = array_keys(CRM_Core_PseudoConstant::accountOptionValues("contribution_status", NULL, " AND v.name IN ('Pending', 'Overdue')")); $statusId = implode(',', $statusId); + $select = "payment.pledge_id, payment.scheduled_amount, pledge.contact_id"; $sqlPayment = " SELECT min(payment.scheduled_date) as scheduled_date, - payment.pledge_id, - payment.scheduled_amount, - pledge.contact_id + {$select} FROM civicrm_pledge_payment payment LEFT JOIN civicrm_pledge pledge @@ -479,7 +479,7 @@ public function postProcess() { WHERE payment.status_id IN ({$statusId}) - GROUP BY payment.pledge_id"; + GROUP BY {$select}"; $daoPayment = CRM_Core_DAO::executeQuery($sqlPayment); diff --git a/CRM/Report/Form/Pledge/Pbnp.php b/CRM/Report/Form/Pledge/Pbnp.php index e90e03b00d06..5bbf9d13d6b9 100644 --- a/CRM/Report/Form/Pledge/Pbnp.php +++ b/CRM/Report/Form/Pledge/Pbnp.php @@ -248,6 +248,7 @@ public function select() { } } } + $this->_selectClauses = $select; $this->_select = "SELECT " . implode(', ', $select) . " "; } @@ -301,10 +302,12 @@ public function from() { } public function groupBy() { - $this->_groupBy = " - GROUP BY {$this->_aliases['civicrm_pledge']}.contact_id, - {$this->_aliases['civicrm_pledge']}.id, - {$this->_aliases['civicrm_pledge']}.currency"; + $groupBy = array( + "{$this->_aliases['civicrm_pledge']}.contact_id", + "{$this->_aliases['civicrm_pledge']}.id", + "{$this->_aliases['civicrm_pledge']}.currency", + ); + $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy); } public function orderBy() { diff --git a/CRM/Report/Form/Pledge/Summary.php b/CRM/Report/Form/Pledge/Summary.php index 04f10bbae7c1..a5b4d022d91b 100644 --- a/CRM/Report/Form/Pledge/Summary.php +++ b/CRM/Report/Form/Pledge/Summary.php @@ -273,12 +273,15 @@ public function groupBy() { ) { $this->_rollup = " WITH ROLLUP"; } - $this->_groupBy = "GROUP BY " . implode(', ', $this->_groupBy) . - " {$this->_rollup} "; + $groupBy = $this->_groupBy; + $this->_groupBy = "GROUP BY " . implode(', ', $this->_groupBy); } else { - $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id"; + $groupBy = "{$this->_aliases['civicrm_contact']}.id"; + $this->_groupBy = "GROUP BY {$groupBy}"; } + $this->appendSelect($this->_selectClauses, $groupBy); + $this->_groupBy .= " {$this->_rollup}"; } /** diff --git a/CRM/Utils/Weight.php b/CRM/Utils/Weight.php index 352b6616e2d6..8da6d84a157e 100644 --- a/CRM/Utils/Weight.php +++ b/CRM/Utils/Weight.php @@ -53,7 +53,7 @@ class CRM_Utils_Weight { */ public static function correctDuplicateWeights($daoName, $fieldValues = NULL, $weightField = 'weight') { $selectField = "MIN(id) AS dupeId, count(id) as dupeCount, $weightField as dupeWeight"; - $groupBy = "$weightField having dupeCount>1"; + $groupBy = "$weightField having count(id)>1"; $minDupeID = CRM_Utils_Weight::query('SELECT', $daoName, $fieldValues, $selectField, NULL, NULL, $groupBy);