Mi experiencia DBA no va mucho más allá del simple almacenamiento + recuperación de datos de estilo CMS, por lo que esta puede ser una pregunta tonta, ¡no lo sé!
Tengo un problema por el cual necesito buscar o calcular los precios de vacaciones para un determinado tamaño de grupo y un cierto número de días dentro de un cierto período de tiempo. P.ej:
¿Cuánto cuesta una habitación de hotel para 2 personas por 4 noches en cualquier momento de enero?
Tengo datos de precios y disponibilidad de, digamos, 5000 hoteles almacenados de esta manera:
Hotel ID | Date | Spaces | Price PP
-----------------------------------
123 | Jan1 | 5 | 100
123 | Jan2 | 7 | 100
123 | Jan3 | 5 | 100
123 | Jan4 | 3 | 100
123 | Jan5 | 5 | 100
123 | Jan6 | 7 | 110
456 | Jan1 | 5 | 120
456 | Jan2 | 1 | 120
456 | Jan3 | 4 | 130
456 | Jan4 | 3 | 110
456 | Jan5 | 5 | 100
456 | Jan6 | 7 | 90
Con esta tabla, puedo hacer una consulta así:
SELECT hotel_id, sum(price_pp)
FROM hotel_data
WHERE
date >= Jan1 and date <= Jan4
and spaces >= 2
GROUP BY hotel_id
HAVING count(*) = 4;
resultados
hotel_id | sum
----------------
123 | 400
La HAVING
cláusula aquí se asegura de que haya una entrada para cada día entre mis fechas deseadas que tenga los espacios disponibles. es decir. El hotel 456 tenía 1 espacio disponible el 2 de enero, la cláusula HAVING devolvería 3, por lo que no obtenemos un resultado para el hotel 456.
Hasta aquí todo bien.
Sin embargo, ¿hay alguna manera de averiguar todos los períodos de 4 noches en enero donde hay espacio disponible? Podríamos repetir la consulta 27 veces, incrementando las fechas cada vez, lo que parece un poco incómodo. O otra forma podría ser almacenar todas las combinaciones posibles en una tabla de búsqueda de esta manera:
Hotel ID | total price pp | num_people | num_nights | start_date
----------------------------------------------------------------
123 | 400 | 2 | 4 | Jan1
123 | 400 | 2 | 4 | Jan2
123 | 400 | 2 | 4 | Jan3
123 | 400 | 3 | 4 | Jan1
123 | 400 | 3 | 4 | Jan2
123 | 400 | 3 | 4 | Jan3
Y así. Tendríamos que limitar el número máximo de noches y el número máximo de personas que buscaríamos, por ejemplo, noches máximas = 28, personas máximas = 10 (limitado al número de espacios disponibles para ese período establecido que comienza en esa fecha).
Para un hotel, esto podría darnos 28 * 10 * 365 = 102000 resultados por año. 5000 hoteles = 500m de resultados!
Pero tendríamos una consulta muy simple para encontrar la estadía más barata de 4 noches en enero para 2 personas:
SELECT
hotel_id, start_date, price
from hotel_lookup
where num_people=2
and num_nights=4
and start_date >= Jan1
and start_date <= Jan27
order by price
limit 1;
¿Hay alguna manera de realizar esta consulta en la tabla inicial sin tener que generar la tabla de búsqueda de filas de 500 m? por ejemplo, ¿generar los 27 resultados posibles en una tabla temporal o alguna otra magia de consulta interna?
Por el momento, todos los datos se guardan en una base de datos de Postgres. Si es necesario para este propósito, ¿podemos mover los datos a otra cosa más adecuada? No estoy seguro de si este tipo de consulta se ajusta al mapa / reduce los patrones para las bases de datos de estilo NoSQL ...