Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match row value as variable for parameter in sibling results?

I have 2 db calls that run a loop to get all results.

First I'm getting the results relative to current year.

Second I'm getting results relative to previous year (-1).

How can align the month in the output of second loop to same month from the first loop?

public function cargovolumes_cy() {
    global $wpdb;

    $cargodb = new $wpdb('root', 'devpw', 'exdb', 'localhost');

    $currentmonthtxt = date('M');

    $currentyear = date('Y');

    $cargovolume_cy = array();

    foreach($cargodb->get_results(
        "
        SELECT    *, SUM(tonneCount)
        FROM      volumes
        WHERE year = $currentyear
        GROUP BY terminal, year, month
        ORDER BY month desc, year desc
        "
    )  as $key => $row) {
        $tonnages = $row->tonneCount;
        $terminal = $row->terminal;
        $year = $row->year;
        $month = $row->month;
        $cargovolume_cy[] = 
        '<h4 class="cv-terminal-title">'.$terminal.' </h4>'. 
        '<div class="cargovolumes_cy">'.
        '<div class="cargovolumes_cy-dates cvrow-'.$month.'-'.$year.'">'.
        '<span class="cy-month"> '.$month.' </span>'. 
        '<span class="cy-year"> '.$year.' </span></div>'. 
        '<div class="cy-year-bar"><div class="cy-tonnage-bar">&nbsp;</div>'.
        '<span class="cy-tonnage" value="'.$tonnages.'"> '.$tonnages.' </span></div>'.
        '</div>';
    };

    return $cargovolume_cy;

}

public function cargovolumes_ly() {
    global $wpdb;

    $cargodb = new $wpdb('root', 'devpw', 'exdb', 'localhost');

    // $stable = $shipdb->get_results("SELECT * FROM volumes", ARRAY_A);

    $currentmonthtxt = date('M');

    $currentyear = date('Y');

    $cargovolume_ly = array();

    foreach($cargodb->get_results(
        "
        SELECT    *, SUM(tonneCount)
        FROM      volumes
        WHERE year = $currentyear -1
        GROUP BY terminal, year, month
        ORDER BY month desc, year desc
        "
    )  as $key => $row) {
        $tonnages = $row->tonneCount;
        $terminal = $row->terminal;
        $year = $row->year;
        $month = $row->month;
        $cargovolume_ly[] = 
        '<div class="cargovolumes_ly">'. 
        '<div class="cargovolumes_ly-dates">'.
        '<span class="ly-month"> '.$month.' </span>'. 
        '<span class="ly-year"> '.$year.' </span></div>'. 
        '<div class="ly-year-bar"><div class="ly-tonnage-bar">&nbsp;</div>'.
        '<span class="ly-tonnage" value="'.$tonnages.'"> '.$tonnages.' </span></div>'.
        '</div>';
    };

    return $cargovolume_ly;

}

The result should output 2 elements with matched months and years. Instead I'm getting the most recent month in the first output, paired with the last month of the year in the second output.

Below is container element:

@for ($i = 0; $i < min(count($cargovolumes_cy), count($cargovolumes_ly)); $i++)
<div class="page_cargovolumes-info_grid-cy_item">
  {!! $cargovolumes_cy[$i] !!}
  {!! $cargovolumes_ly[$i] !!}
</div>
@endfor
like image 734
canacast Avatar asked Sep 01 '19 22:09

canacast


2 Answers

You might just be overcomplicating this.

Instead of running two sql queries one after the other, it is possible to build a SQL query that generates one record per terminal and per month, with the sum of volumes of this year and of last year in two separated columns. Thi is called conditional aggregation.

Consider:

SELECT 
    terminal, 
    month, 
    SUM(CASE WHEN year = YEAR(CURDATE())     THEN tonneCount ELSE 0 END) tonnage_cy,
    SUM(CASE WHEN year = YEAR(CURDATE()) - 1 THEN tonneCount ELSE 0 END) tonnage_ly
FROM volumes
WHERE year >= YEAR(CURDATE()) - 1
GROUP BY terminal, month
ORDER BY month desc

NB:

  • SELECT * with GROUP BY is not a good practice, and might generate errors in non-ancient MySQL versions; you would better explicitly list the columns that you want to return (and add all non-aggregated columns to the GROUP BY clause), as shown in the above SQL
  • you can compute the current year directly from sql with YEAR(CURDATE()) instead of using PHP's date() function.
like image 78
GMB Avatar answered Nov 05 '22 10:11

GMB


You can fill your arrays in the other way in order to somehow store months in them like so:

$cargovolume_cy["$terminal-$month-$year"] = 
        '<h4 class="cv-terminal-title">'.$terminal.' </h4>'. 
        '<div class="cargovolumes_cy">'.
        '<div class="cargovolumes_cy-dates cvrow-'.$month.'-'.$year.'">'.
        '<span class="cy-month"> '.$month.' </span>'. 
        '<span class="cy-year"> '.$year.' </span></div>'. 
        '<div class="cy-year-bar"><div class="cy-tonnage-bar">&nbsp;</div>'.
        '<span class="cy-tonnage" value="'.$tonnages.'"> '.$tonnages.' </span></div>'.
        '</div>';

Then, in the container element write something like this:

@foreach ($cargovolumes_cy as $key_1 => $volume_cy)
    @foreach ($cargovolumes_ly as $key_2 => $volume_ly)
        @if (explode('-', $key_1)[1] == explode('-', $key_2)[1])
            <div class="page_cargovolumes-info_grid-cy_item">
              {!! $volume_cy !!}
              {!! $volume_ly !!}
            </div>
        @endif
    @endforeach
@endforeach
like image 4
Gevorg Melkumyan Avatar answered Nov 05 '22 12:11

Gevorg Melkumyan