phpmysqlgroup-bymysqli-multi-query

mysql multiple group by


Good time! Tell me how to optimize this query and, if possible, unite it into one!

$query  = "SELECT external_source_id FROM smf_tds_unique_statistic WHERE ".$dateRange." GROUP BY external_source_id ORDER BY external_source_id ASC;";
$query .= "SELECT sources_id FROM smf_tds_unique_statistic WHERE ".$dateRange." GROUP BY sources_id ORDER BY sources_id ASC;";
$query .= "SELECT ip_country FROM smf_tds_unique_statistic WHERE ".$dateRange." GROUP BY ip_country ORDER BY ip_country ASC;";
$query .= "SELECT cidr FROM smf_tds_unique_statistic WHERE ".$dateRange." GROUP BY cidr ORDER BY cidr ASC;";

if (mysqli_multi_query($db, $query)) {
do {
    if ($result = mysqli_store_result($db)) {

        while ($row = mysqli_fetch_row($result)) {
            $val = $row[0];
            if ($val != '') {
                $options .= '<li class="select_input_option_item" value="'.$val.'">'.$val.'</li>';
            }
        }
        array_push($optionsArr, $options);
        $options = '';

        mysqli_free_result($result);
    }

    if (!mysqli_more_results($db)) break;
} while (mysqli_next_result($db));} mysqli_close($db);

Solution

  • It appears your queries only need to get lists of distinct values in four columns.

    Here's a way you can do this with one query:

    SELECT 
      GROUP_CONCAT(DISTINCT external_source_id ORDER BY external_source_id) AS external_source_id,
      GROUP_CONCAT(DISTINCT sources_id ORDER BY sources_id) AS sources_id,
      GROUP_CONCAT(DISTINCT ip_country ORDER BY ip_country) AS ip_country,
      GROUP_CONCAT(DISTINCT cidr ORDER BY cidr) AS cidr
    FROM smf_tds_unique_statistic 
    WHERE $dateRange
    

    The values will be returned in a single row, and each column will contain a string which is a comma-separated list of distinct values from each respective column in the database. You'll have to use PHP to explode() each of these strings into an array.

    The only way you might optimize this query is to create an index for your $dateRange condition to use. But you haven't included the value of $dateRange in your question, so I'll leave it to you to figure that out.