Начало » Использование СУБД » Microsoft SQL Server » Поиск по диапазону значений 
	
		
		
			| Поиск по диапазону значений [сообщение #3248] | 
			Thu, 05 October 2023 00:22   | 
		 
		
			
				
				
				
					
						  
						Stephov
						 Сообщений: 3 Зарегистрирован: October 2023 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		Всем привет. 
Гостиница предоставляет данные о своих номерах, в виде кодов, например: 0103031206100002. 
Первые 2 символа - это количество мест для взрослых (01), следующие 2 символа - места для детей (03). Затем идет описание диапазона возрастов для каждого из детей. Разделим оставшиеся символы по 4: 0312, 0610, 0002. Получается 1 ребенок в возрасте от 3 до 12 лет, один 6-10 лет и один 0-2 лет. 
 
Было решено создать 2 таблицы. Первая хранит детальные данные о комнате:  
Room 
Id   Code                             Type   ChildCount     Price и тд. 
1    0103031206100002       Type1  3                  125 
 
А вторая - это описание диапазонов возрастов детей, на основании кода. Получается как-то так: 
ChildAccomodation 
Id      Code                             ChMinAge     ChMaxAge 
1       0103031206100002        3                 12 
2       0103031206100002        6                 10 
3       0103031206100002        0                 2 
 
При поиске комнаты, нам передается количество и возрасты детей. Например 3 ребенка, в возрасте: 5,7 и 2 года. Надо отметить, что детей может быть от 1 до 5. В результате надо показать строку из таблицы Room: комнату, где можно разместить всех детей. 
 
Требования такие: если хоть один из возрастов не входит в диапазон (например, есть один ребенок 13 лет), то результат запроса должен быть пустым. 
Если указано 2 ребенка в возрасте 1 года, то результат опять должен быть пустым, поскольку в комнате предусмотрено только одно место для диапазона 0-2. 
Для ребенка 7 лет подходит как диапазон 3-12, так и 6-10. Но тут загвоздка в том, что если для 7-летнего найти строку с диапазоном 3-12, то 5-летний останется за бортом: ни 0-2, ни 6-10 ему уже не подойдут. Для 7-летнего нужно найти диапазон 6-10, чтобы 5-летнему подошел диапазон 3-12, а 2-летнему 0-2, в этом случае все дети разметятся.  
 
Ломаю голову уже 2 дня.. может кто сталкивался с подобной задачей? 
Заранее спасибо.
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	
		
		
			| Re: Поиск по диапазону значений [сообщение #3283 является ответом на сообщение #3252] | 
			Sat, 07 October 2023 16:32    | 
		 
		
			
				
				
				
					
						  
						Stephov
						 Сообщений: 3 Зарегистрирован: October 2023 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		Спасибо вам Большое! 
Навели меня на мысль, я добавил поле и сузил диапазон по максимуму: записал по одной строке для каждого возраста. 
Таблица приняла такой вид. (пардон, не знаю как красиво отформатировать) 
Id  Code                ChMinAge    ChMaxAge    ChildAge 
1   0103031206100002    3           12          3 
2   0103031206100002    3           12          4 
3   0103031206100002    3           12          5 
4   0103031206100002    3           12          6 
5   0103031206100002    3           12          7 
6   0103031206100002    3           12          8 
7   0103031206100002    3           12          9 
8   0103031206100002    3           12          10 
9   0103031206100002    3           12          11 
10  0103031206100002    3           12          12 
11  0103031206100002    6           10          6 
12  0103031206100002    6           10          7 
13  0103031206100002    6           10          8 
14  0103031206100002    6           10          9 
15  0103031206100002    6           10          10 
16  0103031206100002    0           2           0 
17  0103031206100002    0           2           1 
18  0103031206100002    0           2           2 
 
Сразу надо отметить, что полуаемый Code затем соединяется с другой таблицей, в которой есть поле с необходимым количеством детей. Добавляется проверка на равность по этому полю, иначе можно получить неверные данные, если искать, например, двоих в возрасте 10 лет. 
Получилось так: 
DECLARE 
	@childAge1 AS FLOAT = 2,
	@childAge2 AS FLOAT = 5,
	@childAge3 AS FLOAT = 7,
	@childAge4 AS FLOAT = null,
	@childAge5 AS FLOAT = null;
DECLARE @Childs TABLE 
(ChildAge FLOAT);
INSERT INTO @Childs (ChildAge)
VALUES
	(@childAge1),
	(@childAge2),
	(@childAge3),
	(@childAge4),
	(@childAge5);
declare @NeededChildsTotal AS INT
select @NeededChildsTotal = COUNT(ChildAge) from @Childs where ISNULL(ChildAge, -1) != -1
select Code, SUM(NeededChildCount) as SumNeededChildCount
from (select ChildAge, COUNT(1) as NeededChildCount from @Childs where ISNULL(ChildAge, -1) != -1 group by ChildAge ) CH
INNER JOIN 
	(select Count(1) as FoundChildCount, Code, ChildAge from NumberRanges group by Code, ChildAge) N
	ON CH.ChildAge = N.ChildAge AND CH.NeededChildCount > 0 AND CH.NeededChildCount <= N.FoundChildCount
GROUP BY Code
HAVING COUNT(FoundChildCount) = @NeededChildsTotal OR SUM(FoundChildCount) = @NeededChildsTotal
  
Чувствую, что не самый оптимальный метод.. но хотя бы рабочий.
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |   
Переход к форуму:
 
 Текущее время: Tue Nov 04 04:03:05 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.01016 секунд 
 |