如何在考虑跳过的ID时将数据库表复制到数组?

时间:2012-01-10 23:56:46

标签: php mysql arrays primary-key skip

我之前设计了我正在处理的网站,以便我只查询数据库以获取每页所需的信息,但是在实现了每个页面上每个表格中需要每个单元格的功能之后(哦,小男孩)我意识到为了优化目的,我应该将它组合成一个大型数据库查询并将每个表抛出一个数组,从而减少SQL调用。

问题在于我希望此数组在数据库中包含跳过的ID(主键)。我会尽量避免错过行/ ID,但我不会管理这些数据,我希望系统能够足够聪明地解决这类问题。

我的方法很简单:

//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];

//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
    $row = mysql_fetch_assoc($localityResult);
    $localityData["id"][$i] = $row["id"];
    $localityData["name"][$i] = $row["name"];
}

//Output
for ($i=1;$i<$localityMax+1;$i++)
{
    echo $i.". ";
    echo $localityData["id"][$i]." - ";
    echo $localityData["name"][$i];
    echo "<br />\n";
}

两个注释:

  1. 是的,我应该将$ localityMax检查移到PHP循环中。

  2. 我故意跳过第一个数组键。

  3. 这里的问题是没有考虑数据库中任何遗漏的密钥,因此它最终输出如下(样本表):

      
        
    1. 1 - Tok
    2.   
    3. 2 - 朱诺
    4.   
    5. 3 - 安克雷奇
    6.   
    7. 4 - 纳什维尔
    8.   
    9. 7 - 查塔努加
    10.   
    11. 8 - 孟菲斯
    12.   
    13. -
    14.   
    15. -
    16.   

    我想在找不到行时写入“Error”或NULL或其他内容,然后继续操作而不会中断事情。我发现我可以检查$ i是否小于$ row [$ i]以查看该行是否被跳过,但我不确定如何纠正它。

    如果需要,我可以提供更多信息或示例数据库转储。我刚刚被困在这个问题上好几个小时,我尝试过的任何工作都没有。如果我犯了任何可怕的错误,我将非常感谢您的帮助和一般反馈。谢谢!


    编辑:我已经解决了!首先,遍历数组以设置NULL值或“Error”消息。然后,在赋值中,在mysql_fetch_assoc()调用之后立即将$ i设置为$ row [“id”]。完整代码如下所示:

    //Run query
    $localityResult = mysql_query("SELECT id,name FROM localities");
    $localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
    $localityMax = $localityMax[0];
    
    //Reset
    for ($i=1;$i<$localityMax+1;$i++)
    {
        $localityData["id"][$i] = NULL;
        $localityData["name"][$i] = "Error";
    }
    
    //Assign table to array
    for ($i=1;$i<$localityMax+1;$i++)
    {
        $row = mysql_fetch_assoc($localityResult);
        $i = $row["id"];
        $localityData["id"][$i] = $row["id"];
        $localityData["name"][$i] = $row["name"];
    }
    
    //Output
    for ($i=1;$i<$localityMax+1;$i++)
    {
        echo $i.". ";
        echo $localityData["id"][$i]." - ";
        echo $localityData["name"][$i];
        echo "<br />\n";
    }
    

    感谢所有人的帮助!

2 个答案:

答案 0 :(得分:0)

在您获得$localityResult之后,您可以将所有ID放入数组中,然后在echo $localityDataStuff之前,查看

if(in_array($i, $your_locality_id_array)) {
  // do your echoing
} else {
  // echo your not found message
}

制作$your_locality_id_array

$locality_id_array = array();
foreach($localityResult as $locality) {
  $locality_id_array[] = $locality['id'];
}

答案 1 :(得分:0)

主键在MySQL中必须是唯一的,因此您最多只能获得一个空白ID,因为MySQL不允许插入重复数据。

如果您使用的是不是主键或唯一键的列,则您的查询将是唯一可以更改的内容:

SELECT id, name FROM localities WHERE id != "";

SELECT id, name FROM localities WHERE NOT ISNULL(id);

编辑:根据OP的澄清创建了一个新的答案。 如果您有一个数字序列要保持不间断,并且数据库表中可能缺少行,则可以使用以下(简单)代码为您提供所需的代码。使用相同的方法,如果您不想从ID $i = ...开始,则1实际上可以设置为数据库序列中的第一个ID。

$result = mysql_query('SELECT id, name FROM localities ORDER BY id');

$data = array();
while ($row = mysql_fetch_assoc($result)) {
    $data[(int) $row['id']] = array(
        'id'   => $row['id'],
        'name' => $row['name'],
    );
}

// This saves a query to the database and a second for loop.
end($data); // move the internal pointer to the end of the array
$max = key($data); // fetch the key of the item the internal pointer is set to

for ($i = 1; $i < $max + 1; $i++) {
    if (!isset($data[$i])) {
        $data[$i] = array(
            'id'   => NULL,
            'name' => 'Erorr: Missing',
        );
    }

    echo "$i. {$data[$id]['id']} - {$data[$id]['name']}<br />\n";
}