Pregunta

Estoy tratando de cargar datos de la base de datos y mostrarlos en una tabla como esta:

http://img196.imageshack.us/img196/1857/cijene.jpg

En la base de datos tengo dos tablas:

cities (id, name)
prices (id, city1_id, city2_id, price)

Por ejemplo, la tabla impresa para 4 ciudades se vería así:

<table>
 <tr>
  <td>city1</td>
  <td> </td>
  <td> </td>
  <td> </td>
 </tr>

 <tr>
  <td> price_city1-city2</td>
  <td>city2</td>
  <td> </td>
  <td> </td>
 </tr>

 <tr>
  <td> price_city1-city3</td>
  <td> price_city2-city3</td>
  <td>city3</td>
  <td> </td>
 </tr>

 <tr>
  <td> price_city1-city4</td>
  <td> price_city2-city4</td>
  <td> price_city3-city4</td>
  <td>city4</td>
 </tr>
</table>

¿Alguien sabe cuál es la declaración PHP para hacer eco de este tipo de tablas?

¿Fue útil?

Solución

// This single query gets all required data
// NOTE: this query assumes that your price data is entered
//   such that from_city always alphabetically precedes to_city!
$sql =
    "SELECT a.name AS from_city, b.name AS to_city, price ".
    "FROM prices ".
    "INNER JOIN cities AS a ON a.id=prices.city1_id ".
    "INNER JOIN cities AS b ON b.id=prices.city2_id";


// connect and do query
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($db, $conn);
$q = mysql_query($sql, $conn);


// Stuff all data into an array for manipulation;
//   keep list of all cities mentioned
$price = array();
$cities = array();
while (($res = mysql_fetch_assoc($q)) !== false) {
    $from = $res['from_city'];
    $cities[ $from ] = true;

    $to = $res['to_city'];
    $cities[ $to ] = true;

    $price[$to][$from] = $res['price'];
}

// Invert to get alphabetical list of cities
$cities = array_keys($cities);
sort($cities);
$num = count($cities);


// some utility functions
function table($rows) {
    return '<table>'.join($rows).'</table>';
}
function row($cells) {
    return '<tr>'.join($cells).'</tr>';
}
function cell($text) {
    $text = (string) $text;
    if (strlen($text)==0)
        $text = '&nbsp;';
    return '<td>'.$text.'</td>';
}


// The data is now in the desired order;
// produce output as HTML table
$rows = array();
for ($to = 0; $to < $num; ++$to) {
    $t = $cities[$to];
    $cells = array();

    for ($from = 0; $from < $to; ++$from) {
        $f = $cities[$from];

        if isset($price[$t]) && isset($price[$t][$f])
            $text = $price[$t][$f];
        else
            $text = '';

        $cells[]= cell($text);
    }

    $cells[]= cell($t);    // add destination-label

    for ($from = $to+1; $from < $num; ++$from)   // pad to proper number of cells
        $cells[]= cell('');

    $rows[]= row($cells);
}
$html = table($rows);


// show results!
echo $html;

Otros consejos

He utilizado un enfoque muy simple para convertir los resultados de una consulta en una tabla HTML. Compruebo que $ query_result es verdadero y obtengo los resultados como una matriz asociativa ...

$query_result = mysqli_query($db, $query);

if ($query_result) {

    while ($columns = mysqli_fetch_assoc($query_result)) {

        echo "<tr>\n";

        foreach ($columns as $name => $column) {
            echo "<td>";
            printf("%s",$columns[$name]);
            echo "</td>\n";
        }

        echo "</tr>\n";
    }
}

EDITAR: Ahora que he podido mirar su mesa, puedo ver que realmente no he respondido a su pregunta. La consulta es obviamente muy importante. ¿La pregunta se convierte en 'cómo creo una consulta que devuelve resultados que se pueden convertir en una tabla con mi enfoque simple?'

Espero que alguien más tenga algunas ideas.

Esto está algo al borde de la practicidad, pero estoy abordando este problema más como un ejercicio en " hacerlo bien. "

Haría una simple selección de cada tabla y la insertaría en una matriz:

$query1 = "SELECT * FROM cities";
$query2 = "SELECT * FROM prices";

$results1 = mysql_query( $query1 );
$results2 = mysql_query( $query2 );

while( $rows = mysql_fetch_array( $results1 ) ) $cities[] = $row['name'];
while( $rows = mysql_fetch_array( $results2 ) ) $prices[] = array(
                                                               $row['city1_id'],
                                                               $row['city2_id'], 
                                                               $row['name']
                                                            );

Luego usaría esto para crear dinámicamente dos listas de JavaScript:

$java_array1 = "var Cities = new Array;\n";
foreach( $cities as $key=>$city ) $java_array1 .= "Cities[$key] = \"$city\";\n";
$java_array2 = "var Prices = new Array;\n";
foreach( $cities as $key=>$price ) $java_array2 .= "Prices[$key] = new Array(
                                                                     \"{$price[0]}\",
                                                                     \"{$price[1]}\",
                                                                     \"{$price[2]}\",
                                                                  );\n";

Luego generaría una tabla con identificadores cuidadosamente diseñados para cada celda. Usaría un código muy similar al de la primera respuesta, pero le daría a cada celda una identificación única de "cell-<row>-<col>".

Lo último que haría sería crear algunos onload javascript que llenarían la tabla usando los emparejamientos apropiados. Mi javascript está bastante oxidado, pero se vería así (NOTA: sigue el pseudocódigo):

n = 1;
for( var i in cities )
{
    // set city names on the diagonal
    document.getElementById( 'cell-'&i&'-'&i ).innerHTML = names[i];
    n = n + 1;
}

for( var j in prices )
{
    // use the city IDs in the prices array (see earlier code initializing
    // prices array) to place the prices
    document.getElementById( 'cell-'&prices[1]&'-'&prices[2] ).innerHTML = prices[0];
}

Casi seguro que estropeé algunos de esos javascript; utilizar bajo su propio riesgo.

Esto es mucho más complejo que la respuesta más simple dada anteriormente, pero esta es la única forma en que puedo pensar en hacerlo para que tenga & "; sentido. &"; Básicamente, con este método, coloca todo donde debería estar, y no tiene que preocuparse por tablas extrañas y selecciones extrañas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top