viernes, 9 de noviembre de 2012

28. Cláusula Group By de SQL.


Entre las muchas posibilidades que nos brinda SQL, una es agrupar registros y obtener información resumida de tablas.

En nuestro problema, un listado interesante sería mostrar la cantidad de alumnos inscriptos por curso. Para resolver de una manera sencilla esta situación, SQL nos permite agrupar los registros de la tabla "alumnos" por la columna "codigocurso" y contar la cantidad de registros que hay por cada código de curso igual.
El programa que nos permite resolver este problema es el siguiente:


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select count(alu.codigo) as cantidad, 
                         nombrecurso from alumnos as alu
                       inner join cursos as cur on cur.codigo=alu.codigocurso
                       group by alu.codigocurso", $conexion) or
  die("Problemas en el select:".mysql_error());
while ($reg=mysql_fetch_array($registros))
{
  echo "Nombre del curso:".$reg['nombrecurso']."<br>";
  echo "Cantidad de inscriptos:".$reg['cantidad']."<br>";
  echo "<hr>";
}
mysql_close($conexion);
?>
</body>
</html> 
 
Hay varias partes importantes en este código; primero, en el select indicamos que cuente la cantidad de registros de la tabla "alumnos":


"select count(alu.codigo) as cantidad, 
                         nombrecurso from alumnos as alu
 
Pero, como veremos más adelante, en 'cantidad' no se almacena la cantidad total de registros de la tabla "alumnos" debido a que más adelante empleamos la cláusula group by.

Como necesitamos rescatar el nombre del curso hacemos el apareo con la tabla "cursos":


   inner join cursos as cur on cur.codigo=alu.codigocurso
 
Por último en la sentencia select de SQL disponemos la cláusula group by:


   group by alu.codigocurso"
 
Con esta cláusula se hace un corte de control por cada grupo de registros que tienen el mismo código de curso almacenado.

Luego mostramos el nombre de curso con la cantidad de inscriptos para dicho curso:


while ($reg=mysql_fetch_array($registros))
{
  echo "Nombre del curso:".$reg['nombrecurso']."<br>";
  echo "Cantidad de inscriptos:".$reg['cantidad']."<br>";
  echo "<hr>";
}
 
 
PROBLEMA PROPUESTO
 
Confeccionar un programa que muestre el nombre del curso, la cantidad de
inscriptos y todos los inscriptos a dicho curso. Repetir esto con todos
los cursos.

Es decir, en la página debe aparecer algo parecido a:



Nombre del curso:PHP

Cantidad de inscriptos:3

Nombres: Martinez Luis - Rodriguez Pablo - Gonzalez Ana



Nombre del curso:JSP

Cantidad de inscriptos:2

Nombres: Hernandez Hector - Roca Marta 

27. UPDATE (Modificación de un registro trabajando con dos tablas)


Ahora complicaremos un poco la modificación de un registro consultando dos tablas. Supongamos que un alumno desea cambiarse de curso, es decir, se inscribió en uno y quiere borrarse de ese e inscribirse en otro diferente. Debemos mostrar en un "select" el curso actual en el que está inscripto y los otros cursos disponibles en la tabla "cursos".

Para resolver este problema tenemos que plantear tres páginas, una donde ingresemos el mail del alumno, la segunda donde se pueda cambiar el curso y por última una que permita modificar la tabla "alumnos" con el nuevo curso seleccionado.

La primer página de ingreso del mail es:


<html>
<head>
<title>Problema</title>
</head>
<body>
<form action="pagina2.php" method="post">
Ingrese el mail del alumno:
<input type="text" name="mail"><br>
<input type="submit" value="buscar">
</form>
</body>
</html>  
 
La segunda página y la más importante en cuanto a novedades es la siguiente:

<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select * from alumnos
                       where mail='$_REQUEST[mail]'",$conexion) or
  die("Problemas en el select:".mysql_error());
if ($regalu=mysql_fetch_array($registros))
{
?>
<form action="pagina3.php" method="post">
<input type="hidden" name="mailviejo" value="<?php 
  echo $regalu['mail'] ?>">
<select name="codigocurso">
<?php
  $registros=mysql_query("select * from cursos",$conexion) or
    die("Problemas en el select:".mysql_error());
  while ($reg=mysql_fetch_array($registros))
  {
  if ($regalu['codigocurso']==$reg['codigo'])
    echo "<option value=\"$reg[codigo]\" selected>$reg[nombrecurso]</option>";
  else
    echo "<option value=\"$reg[codigo]\">$reg[nombrecurso]</option>";
  }
?>
</select>
<br>
<input type="submit" value="Modificar">
</form>
<?php
}
else
  echo "No existe alumno con dicho mail";
?>
</body>
</html> 
 
La primera consulta de la tabla alumnos es para verificar si existe un alumno con el mail ingresado por teclado:


$registros=mysql_query("select * from alumnos
                       where mail='$_REQUEST[mail]'",$conexion) or
  die("Problemas en el select:".mysql_error());
if ($regalu=mysql_fetch_array($registros))
{
 
En caso de existir un alumno con dicho mail, el if se verifica verdadero y pasamos a poblar el control select con los distintos cursos que contiene la tabla "cursos":


  $registros=mysql_query("select * from cursos",$conexion) or
    die("Problemas en el select:".mysql_error());
  while ($reg=mysql_fetch_array($registros))
  {
  if ($regalu['codigocurso']==$reg['codigo'])
    echo "<option value=\"$reg[codigo]\" selected>$reg[nombrecurso]</option>";
  else
    echo "<option value=\"$reg[codigo]\">$reg[nombrecurso]</option>";
  }
?>
</select>
 
Para que aparezca seleccionado el curso actual debemos inicializar lo marca option con el texto selected. Es decir que el if dentro del while se verifica verdadero una solo vez.

Por último la tercer página procede a registrar el cambio en la tabla "alumnos":


<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("update alumnos
                       set codigocurso=$_REQUEST[codigocurso]
                       where mail='$_REQUEST[mailviejo]'",$conexion) or
  die("Problemas en el select:".mysql_error());
echo "El curso fue modificado con exito";
?>
</body>
</html> 
 
 
PROBLEMA PROPUESTO
 
Confeccionar la modificación del mail, nombre y curso de la tabla 
"alumnos". Ingresar por teclado el código de alumno para su búsqueda. 

26. Función count de SQL.


Cuando necesitamos saber la cantidad de registros que cumplen una condición podemos utilizar la función count, por ejemplo si deseamos conocer la cantidad de alumnos que hay en la tabla "alumnos" la codificación será la siguiente:


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select count(*) as cantidad 
                         from alumnos",$conexion) or
  die("Problemas en el select:".mysql_error());
$reg=mysql_fetch_array($registros);
echo "La cantidad de alumnos inscriptos son :".$reg['cantidad'];
?>
</body>
</html>
 
En la sentencia select en vez de indicar los campos de la tabla, colocamos la llamada a la función count pasando como parámetro un asterisco y creando un alias para su posterior recuperación e impresión del dato:


$registros=mysql_query("select count(*) as cantidad 
                         from alumnos",$conexion)
 
El select no tiene cláusula where ya que debemos contar todos los alumnos y no los de algún curso en particular.

La llamada a la función mysql_fetch_array se hace sin estructura condicional o repetitiva ya que sabemos que nos retornará un único registro (en realidad, un registro que tiene una sola columna llamada cantidad, en caso de estar vacía la tabla alumnos, se almacena cero en el alias cantidad):


$reg=mysql_fetch_array($registros);
 
 
PROBLEMA PROPUESTO
 
Confeccionar un programa que muestre por pantalla los nombres de todos 
los cursos y al final la cantidad total de cursos. 

25. Listado (selección de registros de varias tablas - INNER JOIN)


Ahora veremos como imprimir todos los alumnos inscriptos a los cursos junto al nombre del curso donde está inscripto. Los datos se encuentran en las tablas "alumnos" y "cursos".

Debemos aparear el código de curso de la tabla "alumnos" con el código de la tabla "cursos". El código del programa que hace esto es el siguiente:


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select alu.codigo as codigo,nombre,mail,codigocurso, 
                         nombrecurso 
                       from alumnos as alu
                       inner join cursos as cur on cur.codigo=alu.codigocurso", 
                    $conexion) or
  die("Problemas en el select:".mysql_error());
while ($reg=mysql_fetch_array($registros))
{
  echo "Codigo:".$reg['codigo']."<br>";
  echo "Nombre:".$reg['nombre']."<br>";
  echo "Mail:".$reg['mail']."<br>";
  echo "Curso:".$reg['nombrecurso']."<br>";
  echo "<hr>";
}
mysql_close($conexion);
?>
</body>
</html> 
 
Hay varias cosas nuevas cuya sintaxis necesitamos analizar, la primera es como hacer el apareo con la tabla cursos:


   inner join cursos as cur on cur.codigo=alu.codigocurso 
 
Luego de las palabras claves inner join, indicamos la tabla que necesitamos aparear, podemos crear un alias de una palabra mediante la palabra clave as. En el resto de la consulta, en vez de indicar el nombre de la tabla, hacemos referencia al alias(generalmente un nombre más corto).

Seguidamente de la palabra clave on, indicamos los campos por los que apareamos las tablas, en nuestro caso el codigo de la tabla cursos con el codigocurso de la tabla alumnos.

Otro punto a tener en cuenta es indicar en el select qué campos debemos rescatar de las tablas, es decir, indicarle a qué tabla pertenece en el caso que tengan el mismo nombre:


$registros=mysql_query("select alu.codigo as codigo,nombre,mail,codigocurso, 
                         nombrecurso 
                       from alumnos as alu
 
En este caso rescatamos el código del alumno (y no el código de curso). Debemos crear un alias si dos tablas tienen el mismo nombre de campo para evitar confusión; como ocurre aquí con el campo codigo de las tablas alumnos y cursos. También creamos un alias para la tabla alumnos. Cuando rescatamos los datos y los mostramos en la página, hacemos referencia al alias del campo:


while ($reg=mysql_fetch_array($registros))
{
  echo "Codigo:".$reg['codigo']."<br>";
  echo "Nombre:".$reg['nombre']."<br>";
  echo "Mail:".$reg['mail']."<br>";
  echo "Curso:".$reg['nombrecurso']."<br>";
  echo "<hr>";
}
 
 
PROBLEMA PROPUESTO
 
Confeccionar un programa que permita ingresar el código de un alumno y 
nos muestre su nombre, mail y nombre del curso en el cual está 
inscripto. Hacer un formulario donde se ingrese el código de alumno y 
otra página donde se muestren los datos respectivos. Mostrar un mensaje 
si no existe el código de alumno ingresado. 

24. INSERT (y consulta de otra tabla)


Ahora vamos a ver como resolver el problema del alta de un alumno seleccionando el curso de la tabla "cursos".

Es decir, el formulario de carga de datos no es HTML puro ya que debemos cargar el control "select" con los datos de la tabla cursos.

El código por lo tanto queda de la siguiente forma:

<html>
<head>
<title>Problema</title>
</head>
<body>
<form action="pagina2.php" method="post">
Ingrese nombre:
<input type="text" name="nombre"><br>
Ingrese mail:
<input type="text" name="mail"><br>
Seleccione el curso:
<select name="codigocurso">
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select codigo,nombrecurso from cursos",$conexion) or
  die("Problemas en el select:".mysql_error());
while ($reg=mysql_fetch_array($registros))
{
  echo "<option value=\"$reg[codigo]\">$reg[nombrecurso]</option>";
}
?>
</select>
<br>
<input type="submit" value="Registrar">
</form>
</body>
</html>
  
El algoritmo es similar a cuando trabajamos con una tabla, pero el control "select" lo cargamos con los datos de la tabla "cursos":

while ($reg=mysql_fetch_array($registros))
{
  echo "<option value=\"$reg[codigo]\">$reg[nombrecurso]</option>";
}
 
Dentro del while generamos todas las opciones que contiene el "select" imprimiendo el campo nombrecurso y asociando el campo codigo a la propiedad value(que es en definitiva el código que necesitamos rescatar en la otra página)

La página que efectúa el insert es exactamente la misma que vimos anteriormente:

<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la seleccion de la base de datos");
mysql_query("insert into alumnos(nombre,mail,codigocurso) values 
            ('$_REQUEST[nombre]', '$_REQUEST[mail]',
             $_REQUEST[codigocurso])", $conexion) or
  die("Problemas en el select".mysql_error());
mysql_close($conexion);
echo "El alumno fue dado de alta.";
?>
</body>
</html> 
 
 
PROBLEMA PROPUESTO
 
Confeccionar el alta de la tabla alumnos empleando controles de tipo 
"radio" para la selección del curso. 

viernes, 12 de octubre de 2012

23. UPDATE (Modificación de un registro de una tabla)


De las actividades con tablas esta es la más larga. Vamos a resolverlo implementando tres páginas, la primera un formulario de consulta del mail de un alumno, la segunda otro formulario que nos permita cargar su mail modificado y la última registrará el cambio en la tabla.

El formulario de consulta del mail del alumno es similar a problemas anteriores:


<html>
<head>
<title>Problema</title>
</head>
<body>
<form action="pagina2.php" method="post">
Ingrese el mail del alumno:
<input type="text" name="mail"><br>
<input type="submit" value="buscar">
</form>
</body>
</html>
 
La segunda página es la más interesante y con conceptos nuevos:


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("select * from alumnos
                       where mail='$_REQUEST[mail]'",$conexion) or
  die("Problemas en el select:".mysql_error());
if ($reg=mysql_fetch_array($registros))
{
?>
  <form action="pagina3.php" method="post">
  Ingrese nuevo mail:
  <input type="text" name="mailnuevo" value="<?php echo $reg['mail'] ?>">
  <br>
  <input type="hidden" name="mailviejo" value="<?php echo $reg['mail'] ?>">
  <input type="submit" value="Modificar">
  </form>
<?php
}
else
  echo "No existe alumno con dicho mail";
?>
</body>
</html> 
 
Lo primero que podemos observar es que si el if se verifica verdadero se ejecuta un bloque que contiene código HTML:


if ($reg=mysql_fetch_array($registros))
{
?>
  <form action="pagina3.php" method="post">
  Ingrese nuevo mail:
  <input type="text" name="mailnuevo" value="<?php echo $reg['mail'] ?>">
  <br>
  <input type="hidden" name="mailviejo" value="<?php echo $reg['mail'] ?>">
  <input type="submit" value="Modificar">
  </form>
<?php
}
 
Es decir que podemos disponer bloques de PHP dispersos dentro de la página.

Otro concepto importante es como enviar el mail del primer formulario a la tercer página, esto se logra con los controles de tipo "hidden", este tipo de control no se visualiza en el formulario pero se envía al presionar el botón submit.

Si queremos que el control text se cargue con el mail ingresado en el formulario anterior debemos cargar la propiedad value con dicho valor:


  <input type="text" name="mailnuevo" value="<?php echo $reg['mail'] ?>">
 
Por último la pagina3.php es la que efectúa la modificación de la tabla propiamente dicha. Con el mail ingresado en la pagina1.php, el mail modificado en la pagina2.php se efectúa el update.


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");
mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");
$registros=mysql_query("update alumnos
                         set mail='$_REQUEST[mailnuevo]' 
                         where mail='$_REQUEST[mailviejo]'",$conexion) or
  die("Problemas en el select:".mysql_error());
  echo "El mail fue modificado con exito";
?>
</body>
</html> 
 
Tengamos en cuenta que el segundo formulario nos envía dos datos: $_REQUEST[mailnuevo] y $_REQUEST[mailviejo].


PROBLEMA PROPUESTO

Efectuar la modificación del nombre del curso de la tabla "cursos". Para la búsqueda ingresar el código de curso.

22. DELETE (Baja de todos los registros de una tabla)


Para borrar todos los registros de una tabla debemos llamar al comando delete de SQL sin disponer la cláusula where:


<html>
<head>
<title>Problema</title>
</head>
<body>
<?php
$conexion=mysql_connect("localhost","root","") or
  die("Problemas en la conexion");

mysql_select_db("base1",$conexion) or
  die("Problemas en la selección de la base de datos");

mysql_query("delete from alumnos",$conexion) or
  die("Problemas en el select:".mysql_error());
echo "Se efectuó el borrado de todos los alumnos.";
mysql_close($conexion);
?>
</body>
</html> 
 
 
PROBLEMA PROPUESTO 

Efectuar el borrado de todos los registros de la tabla cursos.