Разбиение кол-ва записей из mysql на несколько циклов обработки

Userbanderas

Новичок
Из БД выбираются поля, которые содержат id номера отеля(id_hotel_number). Например выбирается 5 записей, из них 2 поля id_hotel_number == 103 и 3 поля id_hotel_number == 104.
Т.к. имеется два разных id_hotel_number - должно быть два цикла обработки данных. Т.е. обрабатывается id_hotel_number == 103, затем id_hotel_number == 104. Разных id_hotel_number может быть неограниченное кол-во.
Я примерно представляю себе это так:
определяем что имеется 2 id_hotel_number == 103 и выполнили цикл обработки с id_hotel_number == 103, проверяем! Ага, ещё имеется id_hotel_number == 104 - значит делаем ещё один цикл обработки полученных полей с id_hotel_number == 104.

А вот как ОПРЕДЕЛИТЬ что разных id_hotel_number у нас имеется два?
 

Beavis

Banned
создать новый массив, в котором ключами будут id_hotel_number
а потом пройтись по нему двойным foreach
 

Фанат

oncle terrible
Команда форума
сделать запрос с джойном, который сразу выберет все нужные данные без дополнительных циклов обработки.
 

Userbanderas

Новичок
создать новый массив, в котором ключами будут id_hotel_number
а потом пройтись по нему двойным foreach
Всё почти так как мне и нужно. Но вместо того, чтобы в первой итерации обработать только id_hotel_number == 103, а во второй итерации только id_hotel_number == 104, в моём скрипте в обеих итерациях обрабатываются сразу вместе и id_hotel_number == 103 и id_hotel_number == 104.
Как сделать, чтобы в первой итерации обработать только id_hotel_number == 103, а во второй итерации только id_hotel_number == 104?
PHP:
				while ($myrowDate = mysql_fetch_array($resultDate))
				{
					$begSeaArr[]		  = $myrowDate['begSea']; // начальная дата
					$endSeaArr[] 		  = $myrowDate['endSea']; // конечная дата
					$id_hotel_numberArr[$myrowDate['id_hotel_number']] = $myrowDate['id_hotel_number']; // ключи
				}

				foreach($id_hotel_numberArr as $keyIdNmb)
				{
					echo $keyIdNmb."<br>";
					foreach($begSeaArr as $keyBegSea => $begSea)
					{
						echo $begSea."<br>";	
					}
				}
 

Userbanderas

Новичок
Код я привёл, для того чтобы было видно, каким образом я попытался реализовать свою задачу. Прошу Вас только указать в каком направлении мне дальше продолжить, чтобы добиться нужного результата. Или же таким способом, как приведён выше этого не добиться?
 

Userbanderas

Новичок
Прошу прощения, если я Вас обидел таким ответом, возможно я не правильно понял ваш комментарий по поводу выборки нужных данных. Просто насколько мне позволил мой небольшой опыт, сравнительно с Вашим(я не пытаюсь дерзить сейчас!) понять ваш ответ, то я сделал вывод, что нужные данные то, уже выбраны из mysql и теперь их остаётся распределить по нужным циклам и всё, после этого, разные id_hotel_number обработать в отдельных циклах! А как достичь поставленной задачи с помощью mysql, я пока ещё не понял! Буду очень рад, если поможете разобраться!
 

Фанат

oncle terrible
Команда форума
Возможно, я неверно понял вопрос.

Тем не менее,
Разных id_hotel_number может быть неограниченное кол-во.
должно быть два цикла обработки данных.
Эти два предложения противоречат друг другу.
Бесконечного количества разных циклов быть не может.
при бесконечном количестве номеров цикл может быть только один.

Точнее можно ответить только понимая, что это за загадочные циклы обработки и почему они обязательно должны быть разные.
 

Userbanderas

Новичок
Из БД выбираются поля с диапазонами дат(ОТ и ДО), для того, чтобы потом вычислить количество дней(разрыв) между этими диапазонами. К примеру по заданными параметрам поиска по БД у нас выбрано 5 записей(их может быть и больше), которые содержат поля(id, id_hotel_number, begin_date, end_date) и поля равны следующим параметрам:
1) id == 12, id_hotel_number == 103, begin_date == 2012.04.12, end_date == 2012.04.15
2) id == 13, id_hotel_number == 103, begin_date == 2012.04.17, end_date == 2012.04.20
3) id == 15, id_hotel_number == 104, begin_date == 2012.04.22, end_date == 2012.04.25
4) id == 34, id_hotel_number == 104, begin_date == 2012.04.26, end_date == 2012.04.29
5) id == 23, id_hotel_number == 104, begin_date == 2012.05.15, end_date == 2012.06.17
Поле id автоинкрементно, а поле id_hotel_number служит для определения, к какому номеру в гостинице относится запись в БД!
Для того, чтобы посчитать количество дней между диапазонами дат, для определённого номера в гостинице - нужно сначала разграничить полученные данные (поля из mysql) по id_hotel_number, которых у нас имеется в данном случае 2, это 103 и 104. Т.е. получается, что сначала итерация должна выполниться для id_hotel_number == 103, потом, когда id_hotel_number == 103 закончен, передвинуться к id_hotel_number == 104. Иными словами сначала нужно посчитать разрыв между диапазонами дат для id_hotel_number == 103, а потом для id_hotel_number == 104.
Когда я писал в начале темы, что разных id_hotel_number может быть неограниченное кол-во, то имел в виду, что это разные номера в гостинице и их может быть сколько угодно. А два цикла обработки данных имелось ввиду, что две итерации должно быть в конкретном примере.
Я понял свою ошибку(два цикла обработки данных), вместо циклов,нужно было написать две итерации!
Спасибо большое, что нашли в себе силы меня выслушать!
Я пока новичок в программировании, поэтому и обратился сюда, т.к. больше некуда, кроме учебника.
А т.к. учебника часто бывает мало, то приходиться прибегать к помощи опытного специалиста, который поможет тебя направить в нужную сторону!
Очень надеюсь, что сможете чем нибудь помочь!
 

Beavis

Banned
Просто когда фетчишь полученные из таблицы строки, складываешь их не в обычный массив, а в двухмерный, ключами которого является id гостиницы, а значениями - данные из таблицы

В итоге получается такой массив:
PHP:
array(
   103 => array(
      array(id => 12, id_hotel_number => 103, begin_date => 2012.04.12, end_date => 2012.04.15),
      array(id => 13, id_hotel_number => 103, begin_date => 2012.04.17, end_date => 2012.04.20),
   ),
   104 => array(
       array(id => 15, id_hotel_number => 104, begin_date == 2012.04.22, end_date == 2012.04.25),
       array(id => 34, id_hotel_number => 104, begin_date == 2012.04.26, end_date == 2012.04.29),
       array(id => 23, id_hotel_number => 104, begin_date == 2012.05.15, end_date == 2012.06.17),
   ),
);
и его уже обрабатываешь в двойном цикле
 

Фанат

oncle terrible
Команда форума
"потом" ничего вычислять не надо.
как я уже говорил, все надо делать в запросе

Код:
SELECT begin_date, end_date DATEDIFF(begin_date, end_date) as days order by id_hotel_number
выберет все прямо в запросе
 

Beavis

Banned
Шарик, ты балбес

если в таблице 2 строки:
array(id => 12, id_hotel_number => 103, begin_date => 2012.04.12, end_date => 2012.04.15),
array(id => 13, id_hotel_number => 103, begin_date => 2012.04.17, end_date => 2012.04.20),
то надо вычислить разницу между 2012.04.15 и 2012.04.17, т.е. между end_date одной строки и begin_date следующей
 

prolis

Новичок
тогда это задачка для меня
Код:
select t1.id_hotel_number, t1.end_date as begin, min(t2.begin_date) as end,  DATEDIFF(t1.end_date, min(t2.begin_date)) as diff
from table t1,table t2
where t1.id_hotel_number=t2.id_hotel_number
and t2.begin_date>t1.end_date
group by t1.id_hotel_number, t1.end_date
order by 1,2
 

Userbanderas

Новичок
тогда это задачка для меня
Спасибо огромное, что помогли. Я его переделал под свои нужды и теперь он выглядит так:
PHP:
SELECT t1.id_hotel_number, t1.end_season AS
BEGIN , min( t2.begin_season ) AS
END , DATEDIFF( t1.end_season, min( t2.begin_season ) ) AS diff
FROM price_season t1, price_season t2
WHERE 
(
t1.id_hotel_number = t2.id_hotel_number
AND t2.begin_season > t1.end_season AND
t2.`begin_season` <= '2012-04-10' AND t2.`end_season` >= '2012-04-10'
) 
OR (
t1.id_hotel_number = t2.id_hotel_number
AND t2.begin_season > t1.end_season AND t2.`end_season` >= '2012-04-30' AND t2.`begin_season` <= '2012-04-30'
) 
OR (
t1.id_hotel_number = t2.id_hotel_number
AND t2.begin_season > t1.end_season AND t2.`begin_season` >= '2012-04-10' AND t2.`end_season` <= '2012-04-30'
)
Теперь выбираются все даты, которые касаются заданного периода, и после считается кол-во дней между полученными диапазонами дат! Только есть одна загвоздка.
В БД имеется 5 периодов:
id_hotel_number begin_season end_season
103) 2012-04-03 - 2012-04-12
103) 2012-04-15 - 2012-04-19
104) 2012-04-03 - 2012-04-06
104) 2012-04-10 - 2012-04-14
106) 2012-04-04 - 2012-04-07

К примеру, пользователь задал период с 10.04.2012 по 30.04.2012. Значит мы должны получить из БД согласно задаче следующие даты:
id_hotel_number begin_season end_season
103) 2012-04-03 - 2012-04-12
103) 2012-04-15 - 2012-04-19
104) 2012-04-10 - 2012-04-14
и посчитать разницу дней только между:
id_hotel_number begin_season end_season
103) 2012-04-03 - 2012-04-12
103) 2012-04-15 - 2012-04-19
, потому что с id_hotel_number = 104 у нас только один период, поэтому в этой строке нужно установить diff например = 0. А скрипт считает его как два(берётся диапазон, кот. расположен следующим). Так вот, как добиться результата, при котором скрипт не будет считать кол-во дней между периодами, если какой - либо период (id_hotel_number) только один?
 

Userbanderas

Новичок
Привожу дамп таблицы с периодами
PHP:
-- phpMyAdmin SQL Dump
-- version 3.2.3
-- http://www.phpmyadmin.net
--
-- Хост: localhost
-- Время создания: Апр 03 2012 г., 18:08
-- Версия сервера: 5.1.40
-- Версия PHP: 5.2.12

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- База данных: `reservation`
--

-- --------------------------------------------------------

--
-- Структура таблицы `price_season`
--

CREATE TABLE IF NOT EXISTS `price_season` (
  `id` int(4) unsigned NOT NULL AUTO_INCREMENT,
  `id_hotel_number` int(6) NOT NULL,
  `begin_season` date NOT NULL,
  `end_season` date NOT NULL,
  `price` int(6) NOT NULL,
  `quotaNumber` int(3) NOT NULL,
  `del` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=7 ;

--
-- Дамп данных таблицы `price_season`
--

INSERT INTO `price_season` (`id`, `id_hotel_number`, `begin_season`, `end_season`, `price`, `quotaNumber`, `del`) VALUES
(2, 103, '2012-04-03', '2012-04-12', 500, 1, 0),
(3, 103, '2012-04-15', '2012-04-19', 400, 2, 0),
(4, 104, '2012-04-03', '2012-04-06', 700, 1, 0),
(5, 106, '2012-04-04', '2012-04-07', 850, 3, 0),
(6, 104, '2012-04-10', '2012-04-14', 350, 2, 0);
 

Userbanderas

Новичок
Упс! Точно! Просто на форуме не указал, а в самой программе имеется.
Так как же быть с полем, которое нужно выбрать, даже если имеется только одно?
 

prolis

Новичок
как добиться результата, при котором скрипт не будет считать кол-во дней между периодами, если какой - либо период (id_hotel_number) только один?
и
Так как же быть с полем, которое нужно выбрать, даже если имеется только одно?
как-то противоречат.
В любом случае, проверяй t2.begin_season и если он null - подсавляй вместо него t1.end_season
 

Userbanderas

Новичок
Согласен, в противоречивости виноват! До меня дошло уже потом, что если диапазон подходит под заданный пользователем - то его тоже нужно выбрать, хоть он может быть и единстственным!
 
Сверху