I have the following query to obtain an average of a data of the 52 weeks of the year as follows:
$dates = array();
$firstDate = date("Y-m-d", strtotime('first day of January 2016'));
$lastDate  = date("Y-m-d", strtotime('last day of December 2016'));
for($i=strtotime($firstDate); $i<=strtotime($lastDate); $i+=86400 *7){
  array_push($dates, date("Y-m-d", strtotime('monday this week', $i)));
}
for($i = 0; $i < count($dates); $i++){
  $sql = "SELECT pr_products.product,
  CONCAT(YEAR('".$dates[$i]."'),'-',LPAD(WEEK('".$dates[$i]."'),2,'0')) AS Week,
  SUM(IF(sw_sowing.type = 'SW', sw_sowing.quantity,0)) AS PlantSowing,
  SUM(IF(ROUND(DATEDIFF(TIMESTAMPADD(DAY,(6      WEEKDAY('".$dates[$i]."')),'".$dates[$i]."'), sw_sowing.date)/7) >= pr_products.week_production AND sw_sowing.type = 'SW',sw_sowing.quantity,0)) AS              production
FROM (
      SELECT max(sw_sowing.id) AS id
      FROM sw_sowing
      WHERE sw_sowing.status != 0
      AND sw_sowing.id_tenant = :id_tenant
      AND sw_sowing.status = 100
      AND sw_sowing.date <= TIMESTAMPADD(DAY,(6-WEEKDAY('".$dates[$i]."')),'".$dates[$i]."')
     GROUP BY sw_sowing.id_production_unit_detail
     ) AS sw
     INNER JOIN sw_sowing ON sw_sowing.id = sw.id
     INNER JOIN pr_products ON pr_products.id = sw_sowing.id_product
     INNER JOIN pr_varieties ON sw_sowing.id_variety = pr_varieties.id
     INNER JOIN pr_lands ON pr_lands.id = sw_sowing.id_land
     WHERE pr_varieties.code != 1
     AND sw_sowing.id_product = 1
     AND sw_sowing.status = 100
     GROUP BY pr_products.product
     HAVING plantSowing > 0
     ORDER BY pr_products.product";
}
I declare two variables initially that are $firstdate what is the start date and $lastDate which is the end date.
Then I make a for to go through the two dates and keep in an array the dates of Monday of each week.
Then I go through that new array to get the data I need from week to week.
Note: Within the query the variables $dates[$i] are the Monday dates of each week.
Anyway, the query works perfectly because it brings me the data I need from the 52 weeks of the year. The problem is that it takes a while.
I already indexed the tables in mysql, I improve a little but not enough, the query is not actually heavy it takes an average of 0.60 seconds per cycle.
I would like to know if there is a possibility of deleting the for what I am doing and within the query add I do not know, a WHERE that compares the two dates and brings me the data, or if there is any way to improve the query.
I already updated the query with the suggestions of the answer:
$data  = array();
$start = new DateTime('first monday of January 2016');
$end   = new DateTime('last day of December 2016');
$datePeriod = new DatePeriod($start , new DateInterval('P7D') , $end);
$sql = "SELECT product AS product,
            Week AS label,
            ROUND(SUM(harvest)/SUM(production),2) AS value
            FROM (
                    (
                        SELECT pr_products.product,
                               CONCAT(YEAR(:dates),'-', LPAD(WEEK(:dates1),2,'0')) AS Week,
                               SUM(IF(sw_sowing.type = 'SW', sw_sowing.quantity,0)) AS PlantSowing,
                               SUM(IF(ROUND(DATEDIFF(TIMESTAMPADD(DAY,(6-WEEKDAY(:dates2)),:dates3), sw_sowing.date)/7) >= pr_products.week_production AND sw_sowing.type = 'SW',sw_sowing.quantity,0)) AS production,
                               0 AS Harvest
                        FROM (
                                SELECT max(sw_sowing.id) AS id
                                FROM sw_sowing
                                WHERE sw_sowing.status != 0
                                AND sw_sowing.date <= TIMESTAMPADD(DAY,(6-WEEKDAY(:dates4)),:dates5)
                                GROUP BY sw_sowing.id_production_unit_detail
                             ) AS sw
                        INNER JOIN sw_sowing ON sw_sowing.id = sw.id
                        INNER JOIN pr_products ON pr_products.id = sw_sowing.id_product
                        INNER JOIN pr_varieties ON sw_sowing.id_variety = pr_varieties.id
                        WHERE pr_varieties.code != 1
                        AND sw_sowing.id_product = 1
                        AND sw_sowing.status = 100
                        AND sw_sowing.id_tenant = :id_tenant
                        GROUP BY pr_products.product
                        HAVING plantSowing > 0
                        ORDER BY pr_products.product
                    )
                    UNION ALL
                    (
                        SELECT  pr_products.product,
                                CONCAT(YEAR(:dates6),'-', LPAD(WEEK(:dates7),2,'0')) AS Week,
                                0 AS plantSowing,
                                0 AS Production,
                                SUM(pf_harvest.quantity) AS Harvest
                        FROM pf_harvest
                        INNER JOIN pr_products ON pr_products.id = pf_harvest.id_product
                        INNER JOIN pr_varieties ON pr_varieties.id = pf_harvest.id_variety
                        INNER JOIN pf_performance ON pf_performance.id = pf_harvest.id_performance
                        WHERE pf_harvest.date BETWEEN TIMESTAMPADD(DAY,(0-WEEKDAY(:dates8)),:dates9)
                        AND TIMESTAMPADD(DAY,(6-WEEKDAY(:dates10)),:dates11)
                        AND pr_varieties.code != 1
                        AND pf_harvest.id_product = 1
                        AND pf_performance.status = 100
                        AND pf_harvest.id_tenant = :id_tenant1
                        GROUP BY pr_products.product
                        ORDER BY pr_products.product
                        )
                    ) AS sc
            GROUP BY product, label
            ORDER BY label";
       $statement = $this->db->prepare($sql);
       $id_tenant = $this->getIdTenant();
       foreach($datePeriod AS $dates){
         $values = [
           ':dates'      => $dates->format('Y-m-d'),
           ':dates1'     => $dates->format('Y-m-d'),
           ':dates2'     => $dates->format('Y-m-d'),
           ':dates3'     => $dates->format('Y-m-d'),
           ':dates4'     => $dates->format('Y-m-d'),
           ':dates5'     => $dates->format('Y-m-d'),
           ':dates6'     => $dates->format('Y-m-d'),
           ':dates7'     => $dates->format('Y-m-d'),
           ':dates8'     => $dates->format('Y-m-d'),
           ':dates9'     => $dates->format('Y-m-d'),
           ':dates10'    => $dates->format('Y-m-d'),
           ':dates11'    => $dates->format('Y-m-d'),
           ':id_tenant'  => $id_tenant,
           ':id_tenant1' => $id_tenant
         ];
         $result = $this->db->executePrepared($statement , $values);
         $data[] = $result->fetchAll();
      }
$this -> jsonReturnSuccess($data);
 
     
     
    