【问题标题】:looping with a query and lookup table. mysql & php循环查询和查找表。 mysql和php
【发布时间】:2016-03-31 03:40:23
【问题描述】:

我很难找出一个循环。

它们并不是我真正的强项。 ;)

它使用“lookup”类作为查找表,如下所示:(为简洁起见,省略了很多行)

class lookup {
   protected $lookup = array(
    array('rider_count' => '1', 'heat_count' => '1', 'riders_in_heat_1' => '1'),
    array('rider_count' => '2', 'heat_count' => '1', 'riders_in_heat_1' => '2'),
    array('rider_count' => '3', 'heat_count' => '1', 'riders_in_heat_1' => '3'),
    array('rider_count' => '4', 'heat_count' => '1', 'riders_in_heat_1' => '4'),
    array('rider_count' => '5', 'heat_count' => '1', 'riders_in_heat_1' => '5'),
    array('rider_count' => '6', 'heat_count' => '1', 'riders_in_heat_1' => '6'),
    array('rider_count' => '7', 'heat_count' => '1', 'riders_in_heat_1' => '7'),
    array('rider_count' => '8', 'heat_count' => '2', 'riders_in_heat_1' => '4', 'riders_in_heat_2' => '4'),
    array('rider_count' => '9', 'heat_count' => '2', 'riders_in_heat_1' => '5', 'riders_in_heat_2' => '4'),
    array('rider_count' => '10', 'heat_count' => '2', 'riders_in_heat_1' => '5', 'riders_in_heat_2' => '5'),
    array('rider_count' => '11', 'heat_count' => '2', 'riders_in_heat_1' => '6', 'riders_in_heat_2' => '5'),
    array('rider_count' => '12', 'heat_count' => '2', 'riders_in_heat_1' => '6', 'riders_in_heat_2' => '6'),
    array('rider_count' => '13', 'heat_count' => '2', 'riders_in_heat_1' => '7', 'riders_in_heat_2' => '6'),
    array('rider_count' => '14', 'heat_count' => '2', 'riders_in_heat_1' => '7', 'riders_in_heat_2' => '7')
   );
  public function select ($field, $value)
  {
    $list = array();
    foreach ($this->lookup as $count)
    {
      if ($count[$field] == $value)
      {
        $list[] = $count;
      }
    }
    return $list;
  }
}

$classes = new lookup();

我的 php:

      <?php

        // get entries for the event
      function getEntries($class_id, $limit, $offset)
      {
        global $db;
        $getentries = $db->prepare("SELECT entry_id FROM tbl_event_entries WHERE event_id = :event_id AND class_id = :class_id LIMIT :offset, :limit");
        $getentries->bindValue(':event_id', $_GET['event_id']);
        $getentries->bindValue(':class_id', $class_id);
        $getentries->bindValue(':limit', $limit);
        $getentries->bindValue(':offset', $offset);
        $getentries->execute();
        while ($r = $getentries->fetch(PDO::FETCH_ASSOC)) return $r['entry_id'];
      }
        // get count of entries per class
        // get classes for the event
        $geteventclasses = $db->prepare("SELECT class_id FROM tbl_event_classes WHERE event_id = :event_id");
        $geteventclasses->bindValue(':event_id', $_GET['event_id']);
        $geteventclasses->execute();
        while ($r = $geteventclasses->fetch(PDO::FETCH_ASSOC))
        {
        $getentriesperclass = $db->prepare("SELECT entry_id FROM tbl_event_entries WHERE class_id = :class_id AND event_id = :event_id");
        $getentriesperclass->bindValue(':class_id', $r['class_id']);
        $getentriesperclass->bindValue(':event_id', $_GET['event_id']);
        $getentriesperclass->execute();
        $r2count = $getentriesperclass->rowCount();
        $counts[$r['class_id']] = $r2count;
        }
          foreach ($counts as $class => $rider_count)
          {
            $list = $classes->select('rider_count', $rider_count);

            echo "class: ".  $class ."; ridercount: " . $list[0]['rider_count'] ."; heats: ". $list[0]['heat_count'] ." heats, consisting of :<br>\n";


            for ($i = 1; $i <= $list[0]['heat_count']; $i++)
            {
              if ($list[0]['heat_count'] > 0)
              {
                for ($rih = 1; $rih <= $list[0]['riders_in_heat_'.$i]; $rih++)
                {
                  $offset = 1;
                  echo "<li>Heat ". $i ." : ". getEntries($class, $list[0]['riders_in_heat_'.$i], $offset) ." </li>";
                }
                $offset = $offset + $list[0]['riders_in_heat_'.$i];
              }

            }
              echo "</ul>";
          }
       ?>

这最终将构建一个更新查询,将“heat_nbr”和“heat_position”分配给每个entry_id。

任务是从 class_id 中获取 Rider_count 并将其分解,这样我们每场预赛最多只有 7 名车手,并将车手平均分配到每个预赛。

查找是我们确定分发方式的方式。那部分似乎工作得很好。我只是坚持如何让每个骑手分配到一个位置。

我尝试了几种不同的方法,这与我得到的答案一样接近。

非常感谢您朝正确的方向轻推!

在这里查看我到目前为止的输出:

http://home.garyeterry.com/midam/createheats.php?event_id=113

谢谢

表结构:

CREATE TABLE IF NOT EXISTS `tbl_event_entries` (
 `entry_id` int(11) NOT NULL AUTO_INCREMENT,
 `event_id` int(1) DEFAULT NULL,
 `racer_id` int(4) DEFAULT NULL,
 `class_id` int(1) DEFAULT NULL,
 `racing_nbr` varchar(4) DEFAULT NULL,
 `machine_cc` int(2) DEFAULT NULL,
 `brand_id` int(1) DEFAULT NULL,
 `overall_finish` int(1) DEFAULT NULL,
 `xtra_int1` varchar(10) DEFAULT NULL,
 `heat_nbr` int(1) DEFAULT NULL,
 `heat_position` int(1) DEFAULT NULL,
 `heat_row` int(1) DEFAULT NULL,
 `heat_finish` int(1) DEFAULT NULL,
  PRIMARY KEY (`entry_id`),
  UNIQUE KEY `entry_id` (`entry_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=165 ;

【问题讨论】:

  • 这看起来很乱。
  • 它肯定远未完成......
  • 为什么会有第一个 Select 查询?它的目的是什么?看来您的第二个查询也是如此
  • 你能提供你的SQL表的结构吗?
  • 第一个是获取entry_id的函数。这绝对没有按预期工作。它根本没有做 second 的工作。

标签: php mysql arrays loops


【解决方案1】:

今天早上我坚持下去,知道循环是我的问题,并且知道我已经接近我需要的了。在我的主循环中对 $offset 进行一点按摩,它正在按我的需要工作。 ;)

再次感谢那些提供帮助的人。以下是有效的代码。

<?php
session_start();
require_once "../db.class.php";
require_once "../functions.class.php";

$f = new functions();
$event_id = $_POST['id'];
header("Content-Type:application/json; Charset=utf-8");


// -- Function Name : getLookup
// -- Params : $value
// -- Purpose : get count of riders and return distribution of riders and heats
function getLookup($value)
{
    global $db;
    $stmt = $db->prepare("SELECT * FROM tbl_lookup WHERE rider_count = :value");
    $stmt->bindValue(':value', $value);
    $stmt->execute();
    return $r = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// -- Function Name : getEntries
// get entries for the event
// -- Purpose : get entries to determine race orders
function getEntries($class_id, $limit, $offset)
{
    global $db;
    global $event_id;
    $getentries = $db->prepare("SELECT entry_id FROM tbl_event_entries WHERE event_id = :event_id AND class_id = :class_id LIMIT :offset, :limit");
    $getentries->bindValue(':event_id', $event_id);
    $getentries->bindValue(':class_id', $class_id);
    $getentries->bindValue(':limit', $limit);
    $getentries->bindValue(':offset', $offset);
    $getentries->execute();
    while ($r = $getentries->fetch(PDO::FETCH_ASSOC)) return $r['entry_id'];
}
// -- Function Name : getEntriesPerClass
// get count of entries per class
// -- Purpose : get entries per class to feed the lookup function  
function getEntriesPerClass ()
{
    global $db;
    $getentriesperclass = $db->prepare("SELECT tbl_event_entries.class_id, COUNT(tbl_event_entries.entry_id) AS riders, tbl_moto_order.moto_nbr
                                FROM tbl_event_entries
                                JOIN tbl_moto_order ON tbl_event_entries.event_id = tbl_moto_order.event_id AND tbl_event_entries.class_id = tbl_moto_order.class_id
                                WHERE tbl_event_entries.event_id = :event_id
                                GROUP BY tbl_event_entries.class_id
                                ORDER BY moto_nbr;");
    $getentriesperclass->bindValue(':event_id', $_POST['id']);
    $getentriesperclass->execute();
    $counts = array();
    while ($r = $getentriesperclass->fetch(PDO::FETCH_ASSOC)) $counts[$r['class_id']] = $r['riders'];
    return $counts;
}

$counts = getEntriesPerClass();
$race = 1; //set to add value to race_nbr field, increments 1 time for each total heat race

foreach ($counts as $class => $rider_count)
{
    $list = getLookup($rider_count); // lookup to get heat race counts and line ups for each heat.
    // update event classes table with counts so we don't have to loop like crazy to build the printouts
    $assign_class_counts = $db->prepare("UPDATE tbl_event_classes SET nbr_of_heats = :nbr_of_heats, nbr_of_riders_in_heats = :nbr_of_riders_in_heats WHERE event_id = :event_id AND class_id = :class_id");
    $assign_class_counts->bindValue(':nbr_of_heats', $list[0]['heat_count']);
    $assign_class_counts->bindValue(':nbr_of_riders_in_heats', $list[0]['rider_count']);
    $assign_class_counts->bindValue(':event_id',  $_POST['id']);
    $assign_class_counts->bindValue(':class_id', $class);
    $assign_class_counts->execute();

    $offset = 0; // set offset to feet the main query to give us the position in each heat for a rider. Used in the getEntries query.
    for ($i = 1; $i <= $list[0]['heat_count']; $i++)
    {
        if ($list[0]['heat_count'] > 0)
        {
            for ($rih = 1; $rih <= $list[0]['riders_in_heat_'.$i]; $rih++)
            {
                $assignheats = $db->prepare("UPDATE tbl_event_entries SET heat_nbr = :heat_nbr, heat_position = :heat_position, race_nbr = :race_nbr WHERE entry_id = :entry_id");
                $assignheats->bindValue(':heat_nbr', $i);
                $assignheats->bindValue(':heat_position', $rih);
                $assignheats->bindValue(':race_nbr', $race);
                $assignheats->bindValue(':entry_id', getEntries($class, $list[0]['riders_in_heat_'.$i], $offset));
                $assignheats->execute();
                $offset++;
            }
            $race++;
        }
    }
}

echo json_encode(array('status' => true));

【讨论】:

    【解决方案2】:

    尽我所能清理一切,可能并不完美,但应该足以推动正确的方向。

    lookup 类移动到数据库表

    在我看来,将lookup 类的意图转移到数据库表中会更好。想象一下这样的事情:

    CREATE TABLE IF NOT EXISTS `tbl_lookup` (
     `lookup_id` int(11) NOT NULL AUTO_INCREMENT,
     `rider_count` int NOT NULL,
     `heat_count` int NOT NULL,
     `riders_in_heat_1` int NOT NULL,
     `riders_in_heat_2` int,
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
    

    然后插入 lookup 类中的所有数据。

    在您的第一个 SQL 查询中使用 JOIN 和 GROUP BY

    您需要确定给定赛事和班级的骑手人数。您只需加入 tbl_event_classestbl_event_entries 然后 GROUP BY tbl_event_entries.event_id 即可获得这些计数。

    SELECT tec.class_id, tec.event_id, COUNT(tee.event_id) AS entries_per_class
    FROM tbl_event_classes tec
    JOIN tbl_event_entries tee ON tee.event_id = tec.event_id
    WHERE tec.event_id = :event_id
    GROUP BY tee.event_id
    

    清理 PHP

    现在您的 PHP 代码应该更容易理解了。一个主要查询来获取事件和班级,每个班级每个事件的骑手人数。然后,当您遍历该结果集时,确定每场比赛的骑手人数。

    这有点粗糙,但我相信你可以从这里把它擦亮。

    function getEntriesPerClass($event_id) {
        global $db;
    
        $stmt = $db->prepare(
            'SELECT tec.class_id, tec.event_id, COUNT(tee.event_id) AS entries_per_class ' .
            'FROM tbl_event_classes tec ' .
            'JOIN tbl_event_entries tee ON tee.event_id = tec.event_id ' .
            'WHERE tec.event_id = :event_id ' .
            'GROUP BY tee.event_id');
    
        $stmt->bindValue(':event_id', $event_id);
        $stmt->execute();
    
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    function getRidersInHeats($class_id, $event_id, $riders_per_class)
    {
        global $db;
    
        $stmt = $db->prepare(
            'SELECT tl.riders_in_heat_1, tl.riders_in_heat_2 ' .
            'FROM tbl_lookup ' .
            'WHERE class_id = :class_id AND event_id = :event_id AND rider_count = :entries');
    
        $stmt->bindValue(':class_id', $class_id);
        $stmt->bindValue(':event_id', $event_id);
        $stmt->bindValue(':rider_count', $riders_per_class);
    
        $stmt->execute();
    
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    $entriesPerClass = getEntriesPerClass($_GET['event_id']);
    foreach($entriesPerClass as $entry) {
        $riders = getRidersInHeats($entry['class_id'], $entry['event_id'], $entry['entries_per_class']);
    
        echo
            "class     : " . $row['class_id']       . "; " .
            "ridercount: " . $riders['rider_count'] . "; " .
            "heats     : " . $riders['heat_count']  . "<br/>";
    
        echo "Heats, consisting of :<br>\n<ul>";
        echo "<li>Heat 1: " . $riders['riders_in_heat_1'] . "</li>";
    
        $ridersInHeat2 = $riders['riders_in_heat_2'];
        if($ridersInHeat2 > 0) {
            echo "<li>Heat 2: " . $riders['riders_in_heat_2'] . "</li>";
        }
    
        echo "</ul>";
    }
    

    【讨论】:

    • 感谢您的努力,但这里有太多错误,我无法确定其中任何一个。
    • 嘿伙计,代码很简单; 2个查询和一个循环......只需将其分解成几部分。首先获取连接查询,使用 mysql 客户端运行它以查看它是如何工作的,然后将其移动到 php.ini 中。之后得到查找表和相应的功能。之后循环应该很容易。如果你想聊天,我明天会在。
    • 它现在可以工作了。见上面我发布了最终使该死的东西工作的代码。这完全是关于我如何计算偏移量以及我在哪里增加它。
    • 很高兴听到它正在工作!我仍然建议花一些时间看看我要去哪里。更少的数据库 i/o 和更简单的 php 代码;)另外,我认为您会发现将查找类移动到数据库中是有意义的。这样您就不需要推送代码,如果您需要添加/修改查找数据。
    • 我刚刚做了一个快速测试,包含 21 个班级和 130 个条目,整个查找操作以及将车手分配到预赛等等大约需要 2 秒。我对这种表现很满意。在我的查找中,我的数组最多每个班级可能有 50 名车手,我严重怀疑我是否会在比赛中看到这么多车手。我可以进一步构建它,就此而言,将数组移动到数据库查询并仍然使用基本查找类。我稍后会以这种方式测试它。现在这工作完美。到这个应用程序的其他困难部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 2017-09-12
    相关资源
    最近更新 更多