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

发布于 2024-12-25 19:20:43 字数 2237 浏览 4 评论 0原文

我之前设计了我正在开发的网站,这样我只需在数据库中查询每页所需的信息,但在实现了一个需要每个页面上每个表格中的每个单元格的功能之后(天哪),我意识到出于优化目的,我应该将其合并到一个大型数据库查询中,并将每个表放入一个数组中,从而减少 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. 我故意跳过第一个数组键。

这里的问题是数据库中任何丢失的键都没有被考虑到,所以它最终会像这样输出(示例表):

  1. 1 - 托克
  2. 2 - 朱诺
  3. 3 - 安克雷奇
  4. 4 - 纳什维尔
  5. 7 - 查塔努加
  6. 8 - 孟菲斯
  7. -
  8. -

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

如果需要,我可以提供更多信息或示例数据库转储。我已经在这个问题上被困了好几个小时了,我所尝试的一切都不起作用。如果我犯了任何严重的错误,我将非常感谢您的帮助和一般反馈。谢谢你!


编辑:我已经解决了!首先,迭代数组以设置 NULL 值或“错误”消息。然后,在赋值中,在 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";
}

感谢大家的帮助!

I previously designed the website I'm working on so that I'd just query the database for the information I needed per-page, but after implementing a feature that required every cell from every table on every page (oh boy), I realized for optimization purposes I should combine it into a single large database query and throw each table into an array, thus cutting down on SQL calls.

The problem comes in where I want this array to include skipped IDs (primary key) in the database. I'll try and avoid having missing rows/IDs of course, but I won't be managing this data and I want the system to be smart enough to account for any problems like this.

My method starts off simple enough:

//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";
}

Two notes:

  1. Yes, I should probably move that $localityMax check to a PHP loop.

  2. I'm intentionally skipping the first array key.

The problem here is that any missed key in the database isn't accounted for, so it ends up outputting like this (sample table):

  1. 1 - Tok
  2. 2 - Juneau
  3. 3 - Anchorage
  4. 4 - Nashville
  5. 7 - Chattanooga
  6. 8 - Memphis
  7. -
  8. -

I want to write "Error" or NULL or something when the row isn't found, then continue on without interrupting things. I've found I can check if $i is less than $row[$i] to see if the row was skipped, but I'm not sure how to correct it at that point.

I can provide more information or a sample database dump if needed. I've just been stuck on this problem for hours and hours, nothing I've tried is working. I would really appreciate your assistance, and general feedback if I'm making any terrible mistakes. Thank you!


Edit: I've solved it! First, iterate through the array to set a NULL value or "Error" message. Then, in the assignations, set $i to $row["id"] right after the mysql_fetch_assoc() call. The full code looks like this:

//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";
}

Thanks for the help all!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

多孤肩上扛 2025-01-01 19:20:43

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

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

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

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

编辑:根据 OP 的说明创建新答案。
如果您希望保持一个数字序列不被破坏,并且数据库表中可能缺少行,则可以使用以下(简单)代码来满足您的需要。使用相同的方法,如果您不想从 ID:1 开始,您的 $i = ... 实际上可以设置为数据库序列中的第一个 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";
}

Primary keys must be unique in MySQL, so you would get a maximum of one possible blank ID since MySQL would not allow duplicate data to be inserted.

If you were working with a column that is not a primary or unique key, your query would need to be the only thing that would change:

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

or

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

EDIT: Created a new answer based on clarification from OP.
If you have a numeric sequence that you want to keep unbroken, and there may be missing rows from the database table, you can use the following (simple) code to give you what you need. Using the same method, your $i = ... could actually be set to the first ID in the sequence from the DB if you don't want to start at ID: 1.

$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";
}
绮烟 2025-01-01 19:20:43

获得 $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'];
}

After you've gotten your $localityResult, you could put all of the id's in an array, then before you echo $localityDataStuff, check to see

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

To make $your_locality_id_array:

$locality_id_array = array();
foreach($localityResult as $locality) {
  $locality_id_array[] = $locality['id'];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文