¿Cómo puedo copiar una tabla de base de datos a una matriz mientras contabiliza las ID omitidas?

StackOverflow https://stackoverflow.com/questions/8812328

Pregunta

Anteriormente diseñé el sitio web en el que estoy trabajando para que solo consultara la base de datos de la información que necesitaba por página, pero después de implementar una característica que requería cada celda de cada tabla de cada página (oh boy), me di cuenta de Para fines de optimización, debo combinarlo en una sola consulta de base de datos grande y arrojar cada mesa a una matriz, reduciendo así las llamadas SQL.

El problema entra en el que quiero que esta matriz incluya IDS omitidas (clave principal) en la base de datos. Intentaré evitar tener filas/identificaciones faltantes, por supuesto, pero no administraré estos datos y quiero que el sistema sea lo suficientemente inteligente como para tener en cuenta cualquier problema como este.

Mi método comienza lo suficientemente simple:

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

Dos notas:

  1. Sí, probablemente debería mover ese cheque de $ LocalityMax a un bucle PHP.

  2. Estoy omitiendo intencionalmente la primera clave de matriz.

El problema aquí es que no se tiene en cuenta ninguna clave perdida en la base de datos, por lo que termina saliendo de esta manera (tabla de muestra):

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

Quiero escribir "error" o nulo o algo cuando no se encuentre la fila, luego continuar sin interrumpir las cosas. Descubrí que puedo verificar si $ i es menos de $ fila [$ i] para ver si la fila fue omitida, pero no estoy seguro de cómo corregirlo en ese punto.

Puedo proporcionar más información o un volcado de base de datos de muestra si es necesario. Acabo de estar atrapado en este problema durante horas y horas, nada de lo que he probado es funcionar. Realmente agradecería su ayuda y sus comentarios generales si estoy cometiendo algún error terrible. ¡Gracias!


Editar: ¡Lo he resuelto! Primero, ite a través de la matriz para establecer un valor nulo o un mensaje de "error". Luego, en las asignaciones, establezca $ i a $ fila ["id"] justo después de la llamada mysql_fetch_assoc (). El código completo se ve así:

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

¡Gracias por toda la ayuda!

¿Fue útil?

Solución

Las claves primarias deben ser únicas en MySQL, por lo que obtendrá un máximo de una ID en blanco posible ya que MySQL no permitiría insertar datos duplicados.

Si estuviera trabajando con una columna que no es una clave primaria o única, su consulta necesitaría ser lo único que cambiaría:

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

o

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

Editar: creó una nueva respuesta basada en la aclaración de OP. Si tiene una secuencia numérica que desea mantener inútil, y puede faltar filas de la tabla de la base de datos, puede usar el siguiente código (simple) para darle lo que necesita. Usando el mismo método, su $i = ... En realidad, podría establecerse en la primera ID en la secuencia de la DB si no desea comenzar en 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";
}

Otros consejos

Después de que hayas obtenido tu $localityResult, podrías poner todas las identificaciones en una matriz, luego antes de ti echo $localityDataStuff, Checa para ver

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

Para hacer $your_locality_id_array:

$locality_id_array = array();
foreach($localityResult as $locality) {
  $locality_id_array[] = $locality['id'];
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top