Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Asociar la disponibilidad de una habitación con un rango de fechas en sql

Estas en el tema de Asociar la disponibilidad de una habitación con un rango de fechas en sql en el foro de PHP en Foros del Web. Hola, Tengo 2 casas rurales, una sellama casa_1 y la otra casa_2, ¿Sabe alguien cómo asociar cada casa con las tablas de las fechas dia_entrada ...
  #1 (permalink)  
Antiguo 06/03/2014, 14:02
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Asociar la disponibilidad de una habitación con un rango de fechas en sql

Hola,
Tengo 2 casas rurales, una sellama casa_1 y la otra casa_2, ¿Sabe alguien cómo asociar cada casa con las tablas de las fechas dia_entrada y dia_salida?.

Ejemplo: Si alguien quiere reservar la casa_1 y ya está reservada ¿Cómo impido que la reserven de nuevo?

Este es el query para comprobar si las fechas están ocupadas:
Código MySQL:
Ver original
  1. SELECT dia_entrada, dia_salida FROM disponibilidad
  2. WHERE     (dia_entrada BETWEEN '$dia_entrada' AND '$dia_salida')
  3.                  OR (dia_salida BETWEEN '$dia_entrada' AND '$dia_salida')
  4.                  OR (dia_entrada <= '$dia_entrada'  AND dia_salida >= '$dia_salida')
Un saludo

Última edición por gnzsoloyo; 06/03/2014 a las 14:45
  #2 (permalink)  
Antiguo 06/03/2014, 18:16
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

No entiendo, supongo que el tipo ingresa las fechas, tu lanzas esta query, si retorna uno o mas resultados le informas al usuario que la estadia esta ocupada y si quieres, le muestras los resultados que devolvio la query para que sepa en que rangos esta ocupada, si la query no retorna nada es que esta disponible, entonces haces el insert, cual es el problema?
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #3 (permalink)  
Antiguo 07/03/2014, 01:35
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Hola NSD, gracias por tu interés de nuevo.
Ya participaste anteriormente en la construción de este query:

http://www.forosdelweb.com/f18/imped...echas-1093155/

Lo di por solucionado pero, lo de asociar el tipo de casa con las fechas, me está quebrando la cabeza, intentaré explicarme algo mejor:

El problema es que la misma casa no la puedo reservar a dos clientes al mismo tiempo y no se cómo asociarla a la consulta de las fechas. Las fechas por si sólas van vien, me devuelve que en esasa fechas no puedo introducir las mismas fechas pero de esta manera podrían reservar la misma habitación las veces que quieran.

En la misma tabla donde tengo las fechas, tengo otra columna que se llama casas. ¿Sería coestión de enlazar la columna casas con las columnas dia_entrada y dia_salida el la misma consulta?

No se si me he explicado bien pero no se me ocurre atra cosa. ¿podría ser algo así?:
Código MySQL:
Ver original
  1. SELECT casas FROM disponibilidad WHERE
  2. (dia_entrada BETWEEN '$dia_entrada' AND '$dia_salida') OR  
  3. (dia_salida BETWEEN '$dia_entrada' AND '$dia_salida') OR
  4. (dia_entrada <= '$dia_entrada'  AND dia_salida >= '$dia_salida');

Última edición por gnzsoloyo; 07/03/2014 a las 03:21 Razón: Codigo de programacion no permitido en foros de BBDD
  #4 (permalink)  
Antiguo 07/03/2014, 18:13
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

No.

Tu tabla puede ser algo asi:
desde | hasta | id_casa
2014-03-01 | 2014-03-03 | 1
2014-03-06 | 2014-03-09 | 2
2014-03-15 | 2014-03-20 | 1
2014-03-30 | 2014-04-05 | 2

si tu quieres saber, en que fechas esta reservada una casa, por ejemplo la casa 1, entonces usarias esta query:
Código MySQL:
Ver original
  1. SELECT fecha_desde, fecha_hasta FROM disponiblidad WHERE id_casa = 1;

esa query filtraria tu tabla dejando solo estos registros:
desde | hasta | id_casa
2014-03-01 | 2014-03-03 | 1
2014-03-15 | 2014-03-20 | 1

ahora bien, si tu quieres los registros que corresponden a reservas de cualquier casa en un rango de fechas, por ejemplo entre el 2014-03-02 y 2014-03-08 entonces usas esta query:
Código MySQL:
Ver original
  1. SELECT fecha_desde, fecha_hasta FROM disponibilidad WHERE
  2. (dia_entrada BETWEEN '2014-03-02' AND '2014-03-08') OR  
  3. (dia_salida BETWEEN '2014-03-02' AND '2014-03-08') OR
  4. (dia_entrada <= '2014-03-02'  AND dia_salida >= '2014-03-08');

esa query filtraria tu tabla dejando solo estos registros:
desde | hasta | id_casa
2014-03-01 | 2014-03-03 | 1
2014-03-06 | 2014-03-09 | 2

Ahora, tu quieres todos los registros que impide que se reserve una casa determinada en un rango de fechas.

Solo debes juntar las dos condiciones anteriores, y si seguimos con los datos del ejemplo quedaria asi:
Código MySQL:
Ver original
  1. SELECT casas FROM disponibilidad WHERE id_casa=1 AND (
  2. (dia_entrada BETWEEN '2014-03-02' AND '2014-03-08') OR  
  3. (dia_salida BETWEEN '2014-03-02' AND '2014-03-08') OR
  4. (dia_entrada <= '2014-03-02'  AND dia_salida >= '2014-03-08'));

esa query filtraria tu tabla dejando solo estos registros:
desde | hasta | id_casa
2014-03-01 | 2014-03-03 | 1

como veras, el "truco" esta en aprender a filtrar. Partes de un conjunto de resultados generico, que son todas las filas, luego, debes de a poco, ir filtrando segun condiciones, primero sacas de los resultados aquellos que no sean de la casa, luego a ese conjunto que te queda, le sacas los que no afectan a la reserva, los que te quedan, son aquellos que te interesa.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #5 (permalink)  
Antiguo 07/03/2014, 18:26
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Voy a intentar hacer un resumen de este tema, sobre la base de la última consulta propuesta por @NSD.
Como bien te dice, para evitar que salgan las propiedades que estarán ocupadas durante un periodo de tiempo, tienes que filtrar con tres condiciones, si o si:
1) Fecha inicial buscada no debe estar entre el inicio y fin de una locación ya pactada.
2) Fecha final buscada no debe estar entre inicio y fin de una locación pactada.
3) El período de la vigencia de ninguna locación quedar contenido dentro del período buscado.

Personalmente, prefiero escribirla así:
Código MySQL:
Ver original
  1. SELECT casas FROM disponibilidad
  2. WHERE id_casa=1
  3.     AND
  4.     ('2014-03-02'  BETWEEN dia_entrada AND dia_salida
  5.     OR
  6.     '2014-03-08'  BETWEEN dia_entrada AND dia_salida
  7.     OR
  8.     (dia_entrada <= '2014-03-02'  AND dia_salida >= '2014-03-08'));
SI a esto le agregas un índice en la tabla DISPONIBILIDAD sobre el par (dia_entrada, dia_salida), tendrás una buena optimización
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 08/03/2014, 14:39
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Perdonar, puede que no me haya explicado bien.

En el filtrado de la consulta no quiero especificar la fecha con número '2014-03-02' como pone gnzsoloyo si no con las fechas ya introducidas, no una que yo le ponga a la consulta.

La tabla la tengo como dice NSD:

tipo_casa | dia_entrada | dia_salida
--------------------------------------------------------
casa_1 | 06-03-2014 | 09-03-2014
--------------------------------------------------------
casa_2 | 06-03-2014 | 09-03-2014
--------------------------------------------------------
casa_1 | 10-03-2014 | 16-03-2014
--------------------------------------------------------
casa_2 | 10-03-2014 | 16-03-2014
--------------------------------------------------------

La casa_2 se podría reservar en la misma fecha que la csa_1 porque es distinta.

¿Podría ser como dice gnzsoloyo pero comparándola con la fecha introducida por el form?:

Código SQL:
Ver original
  1. SELECT * FROM disponibilidad
  2. WHERE tipo_casa
  3.     AND
  4.     ('dia_entrada'  BETWEEN dia_entrada AND dia_salida
  5.     OR
  6.     'dia_salida'  BETWEEN dia_entrada AND dia_salida
  7.     OR
  8.     (dia_entrada <= 'dia_entrada'  AND dia_salida >= 'dia_salida'));
[/PHP]

Última edición por gnzsoloyo; 08/03/2014 a las 15:52 Razón: falta algo
  #7 (permalink)  
Antiguo 08/03/2014, 15:31
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

He hecho una prueba y no va, me inserta la misma casa con las mismas fechas.


Última edición por gnzsoloyo; 08/03/2014 a las 15:59 Razón: Irrelevante
  #8 (permalink)  
Antiguo 08/03/2014, 15:58
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Cita:
Iniciado por Polu Ver Mensaje
Perdonar, puede que no me haya explicado bien.

En el filtrado de la consulta no quiero especificar la fecha con número '2014-03-02' como pone gnzsoloyo si no con las fechas ya introducidas, no una que yo le ponga a la consulta.

(...)

¿Podría ser como dice gnzsoloyo pero comparándola con la fecha introducida por el form?

Eso es total y absolutamente irrelevante para MySQL. El cómo obtengas las fechas, y cómo las proceses en programación son temas ajenos a la base de datos.
Los ejemplos dados usan constantes para que tu puedas adaptar la lógica de la consulta al uso que le das en tu aplicación.
Es en la aplicación donde preparas la sentencia a usar, por ende, es allí donde deberás controlar el problema.

Cita:
He hecho una prueba y no va, me inserta la misma casa con las mismas fechas.
Eso puede suceder porque estás programando mal los inserts, y no es asunto de MySQL. La base sólo hace lo que le mandas a hacer. Si estás mandando datos erróneamente, no tiene por qué adivinarlo.

Resumiendo: La lógica de la consulta que te proponemos es correcta. Lo que tienes son errores de programación (probablemente de lógica), lo que es OFF TOPIC en el foro.
Postea el problema en el Foro de PHP y y postea el código que usas.

Nota: No pongas código PHP aquí. Las reglas de este foro no lo admiten.

Nota 2: Hay un highlight para SQL y otro para MySQL. Úsalos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 08/03/2014, 16:19
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Gracias gnzsoloyo, lo tendré en cuenta.
  #10 (permalink)  
Antiguo 08/03/2014, 17:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

¿Quieres que mueva el post al foro de PHP?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 09/03/2014, 01:06
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Hola gnzsoloyo,

Ya estuve en el foro php y me aconsejaron que me pasara a este pero, el que me aconsejó no era moderador.

Si eso me favorece, me cambias.

Gracias un saludo
  #12 (permalink)  
Antiguo 09/03/2014, 08:17
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Movido a PHP
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 09/03/2014, 08:18
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Para hacer que las fechas entren en la query, en PHP, los parámetros que lleguen (supongamos por POST), tienen que tener el formato correcto, o MySQL no los reconocerá.
Este sería un ejemplo algo rústico:
Código PHP:
<?php
// Tanto "entrada" como "salida" deben tener el formado AAA-MM-DD. Sin horas
$entrada $_POST['entrada'];
$salida $_POST['salida'];

$db = new mysqli($host$user$pass);
$db->select_db("tuBase");

// El "\n" tiene por único objetivo poner un salto de linea en la cadena, 
// pero no tiene efectos nocivos.
// Lo suelo hacer para que, luego, si necesito visualizar la cadena de la 
// consulta, esta resulte legible, y no un mmarracho continuo y que cueste leer.
$qry "SELECT * FROM disponibilidad \n ";
$qry .= "WHERE tipo_casa \n ";
$qry .= "    AND \n ";
$qry .= "    ('$entrada'  BETWEEN dia_entrada AND dia_salida \n ";
$qry .= "    OR \n ";
$qry .= "    '$salida'  BETWEEN dia_entrada AND dia_salida \n ";
$qry .= "    OR \n ";
$qry .= "    (dia_entrada <= '$entrada'  AND dia_salida >= '$salida'))\n ";
$result $db->query($qry);
// -----------------------------------------------------------------------------------
if($result)
    {
    if(
$result->num_rows>0)
        {
        
// tareas si se encontraron registros
        
}
    else
        {
        
//tareas si no hay registros.
        
}
    }
?>
¿Es esto lo que estás haciendo?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 09/03/2014, 15:04
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

He adaptado tu query a mi conexión porque he intentado conectar a tu manera y parece ser que mi servidor no acepta, puede que sea por la clase mysqli.

Ahora, solo me deja introducir dos asientos, uno con la casa_1 y otro con la csa_2, creo que hemos limitado las casas y no las casas con respecto a las fechas.

Tipo casa | Entrada | Salida
Casa-1 09-03-2014 12-03-2014
Casa-2 09-03-2014 12-03-2014

Lo que intento es poder reservar las mismas casas con otra fecha y si alguien intentara reservar en la fecha ya reservada que salga un aviso diciendo que la casa tal con la fecha tal no está disponible.

Te muestro los tres archivos php:

Para insertar los datos, insertar.php
Código HTML:
</head>
<body>
<H1 class="ENCABEZADOS_DE_TEXTOS">Ejemplo:Iimpedir datos duplicados entre dos fechas con PHP y MySQL</H1>
<FORM ACTION="procesar.php" name="contacto" onSubmit="return formulariodecontacto()">
<TABLE>
<TR>
	<TD><span class="TEXTOS">Tipo de Casa:</span>:</TD>
	<TD> <select name="tipo_casa" id="tipo_casa" width="150px">
          <option>Casa-1</option>
          <option>Casa-2</option>
          </select>
   </TD>
</TR>
<TR>
	<TD class="TEXTOS">Entrada:</TD>
	<TD><INPUT TYPE="text" NAME="dia_entrada" id="dia_entrada" readonly SIZE="20" MAXLENGTH="30"></TD>
</TR>
<TR>
	<TD><span class="TEXTOS">Salida:</span>:</TD>
	<TD><INPUT TYPE="text" NAME="dia_salida"  id="dia_salida" readonly SIZE="20" MAXLENGTH="30"></TD>
</TR>
</TABLE>
<INPUT TYPE="submit" NAME="accion" VALUE="Grabar">
</FORM>
<hr> 
Código PHP:
<?php
    
include("conex.php");
    
$link=Conectarse();
    
$result=mysql_query("select * from disponibilidad",$link);
    
?>
Código HTML:
<table width="250" height="30" text-align="center" border=1 cellpadding=1 cellspacing=1 bordercolor="#999999" bgcolor="#E8E8E8">
  <tr>
    <td width="80"><b class="ENCABEZADOS_DE_TEXTOS">Tipo casa</b></td>
    <td width="80"><b class="ENCABEZADOS_DE_TEXTOS">Entrada</b></td>
    <td width="80"><b class="ENCABEZADOS_DE_TEXTOS">Salida</b> </td>
  </tr> 
Código PHP:
<?php        
    
while($row mysql_fetch_array($result)) {
        
printf("<tr class=Estilo1 ><td > %s</td> <td > %s </td> <td > %s </td></tr>",$row['tipo_casa'], $dia_entrada=date('d-m-Y',strtotime($row['dia_entrada'])), $dia_salida=date('d-m-Y',strtotime($row['dia_salida'])));
    }
    
mysql_free_result($result);
    
mysql_close($link);    
?>
Código HTML:
</table>
</body>
</html> 
Para procesar los datos, procesar.php

Código PHP:
<?php
   
include("conex.php"); 
   
$link=Conectarse(); 
   
$dia_entrada=$_GET['dia_entrada']; 
   
$dia_salida=$_GET['dia_salida'];
   
$tipo_casa=$_GET['tipo_casa'];
      
$buscarmysql_query("SELECT * FROM disponibilidad WHERE tipo_casa AND ('$dia_entrada'  BETWEEN dia_entrada AND dia_salida OR '$dia_salida'  BETWEEN dia_entrada AND dia_salida OR (dia_entrada <= '$dia_entrada'  AND dia_salida >= '$dia_salida'))");   
// -----------------------------------------------------------------------------------
if(mysql_num_rows($buscar)>0) {
    
      echo 
"Esta  fecha no esta disponible. Por favor elija otra.<br>";
      echo 
"<a href=\"javascript:history.back()\">Regresar</a>"
      
} else { 

    
mysql_query("INSERT INTO disponibilidad(tipo_casa, dia_entrada, dia_salida) VALUES ('$tipo_casa', '$dia_entrada', '$dia_salida')");
      
      echo 
"Registro correcto.<br>";
      echo 
"<a href=\"http://www.dikindavi.byethost3.com/pruebas/calendar/insertar.php\">Regresar</a>"
}
?>
Y para conectarse a la DB, conex.php

Código PHP:
<?php 

function Conectarse() 



   if (!(
$link=mysql_connect("sql311.byethost3.com","usuario","password"))) 

   { 

      echo 
"Error conectando a la base de datos."

      exit(); 

   } 

   if (!
mysql_select_db("basedatos",$link)) 

   { 

      echo 
"Error seleccionando la base de datos."

      exit(); 

   } 

   return 
$link



?>

Última edición por Polu; 09/03/2014 a las 15:15 Razón: Se me olvidó algo
  #15 (permalink)  
Antiguo 10/03/2014, 13:55
Avatar de Polu  
Fecha de Ingreso: febrero-2003
Mensajes: 135
Antigüedad: 21 años, 2 meses
Puntos: 0
Respuesta: Asociar la disponibilidad de una habitación con un rango de fechas en sql

Bueno, al final he conseguido lo que quería.

Gracias a gnzsoloyo y a NSD que me han iluminado. Probando y probando, lo he coseguido.

Aquí dejo el código por si alguien quiere practicar:

Código PHP:
Ver original
  1. $buscar = mysql_query ("SELECT dia_entrada, dia_salida, tipo_casa from reservas where ( tipo_casa = '$tipo_casa' )AND (('$dia_entrada' BETWEEN dia_entrada AND date_sub(dia_salida, interval +1 day))
  2. or ('$dia_salida' BETWEEN date_sub(dia_entrada, interval -1 day) AND dia_salida) or (dia_entrada <= '$dia_entrada' AND dia_salida >= '$dia_salida') or (dia_entrada >= '$dia_entrada' AND dia_salida <= '$dia_salida'))");

Un saludo y gracias por vuestra ayuda.

Última edición por Polu; 10/03/2014 a las 13:57 Razón: Se me olvida algo

Etiquetas: asociar, disponibilidad, mysql, rango, select, sql, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:40.