문제

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!

도움이 되었습니까?

해결책

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

다른 팁

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'];
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top