loading..
Русский    English
19:59
листать

Группировка отрезков времени

Войнов П.Е.

Данная работа является переработкой статьи Ицик Бен-Ган в применении к учебной базе "Аэрофлот".

Здесь будет применен только один из вариантов решения, рассмотренных в вышеуказанной статье.

Рассмотрим следующую задачу: 

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

Для работы нам понадобится следующая информация: идентификатор компании, дата-время взлета и посадки самолета.

Примечание: для краткости и удобства восприятия, я буду создавать представления, которые будут использоваться по ходу решения задачи. Стоит заметить, что впоследствии легко можно будет "развернуть" получившееся решение в один " select ".

Итак.

Представление vw_trip

  1. CREATE VIEW dbo.vw_trip
  2. AS
  3. SELECT DISTINCT id_comp,
  4. dt_out = date + time_out,
  5. dt_in = date + time_in + CASE WHEN time_out > time_in THEN 1 ELSE 0 END
  6. FROM trip t JOIN
  7. pass_in_trip pt ON t.trip_no = pt.trip_no

Основная трудность решения заключается в том, что нам не известно, сколько рейсов могут организовывать непрерывный интервал времени, в течение которого в воздухе находился хотя бы один самолет компании (в дальнейшем "интервал").

Для нахождения начала "интервала" воспользуемся таким фактом: начало "интервала" совпадает со стартом самолета, если в этот момент ни какой другой самолет компании не находится в воздухе. Или, другими словами, начало "интервала" совпадает со стартом самолета, если не существует других рейсов компании, которые уже взлетели, но еще не приземлились.

Представление vw_dt_start

  1. CREATE VIEW dbo.vw_dt_start
  2. AS
  3. SELECT DISTINCT id_comp, dt_out
  4. FROM vw_trip t
  5. WHERE NOT EXISTS( SELECT 1
  6. FROM vw_trip
  7. WHERE id_comp = t.id_comp AND
  8. dt_out < t.dt_out AND
  9. dt_in > = t.dt_out
  10. )

Пояснения:

dt_out < t.dt_out - строгое неравенство, дабы в проверку не попал сам рассматриваемый рейс;

dt_in > = t.dt_out - нестрогое неравенство; проверяем также ситуацию, когда один самолет взлетает, а другой в это время садится ("интервал" не разрывается);

DISTINCT - убираем дублирование записей на случай одновременного взлета двух или более самолетов.

Время окончания "интервала" находится аналогичным образом.

Представление vw_dt_end

  1. CREATE VIEW dbo.vw_dt_end
  2. AS
  3. SELECT DISTINCT id_comp, dt_in
  4. FROM vw_trip t
  5. WHERE NOT EXISTS(SELECT 1
  6. FROM vw_trip
  7. WHERE id_comp = t.id_comp AND
  8. dt_out <= t.dt_in AND
  9. dt_in > t.dt_in
  10.  
  11. )

Теперь нам осталось соединить времена начала и окончания "интервалов". Так как интервалы не пересекаются, то можно утверждать, что время окончания "интервала" - это минимальное время из всех vw_dt_end.dt_in , превосходящих рассматриваемое время начала "интервала".

Представление vw_result

  1. CREATE VIEW dbo.vw_result
  2. AS
  3. SELECT name_comp = (SELECT [name]
  4. FROM company
  5. WHERE id_comp = vw_dt_start.id_comp
  6. )
  7. vw_dt_start.dt_out, dt_in = MIN(vw_dt_end.dt_in)
  8. FROM vw_dt_start JOIN
  9. vw_dt_end ON vw_dt_start.id_comp = vw_dt_end.id_comp AND
  10. vw_dt_start.dt _out < vw_dt_end.dt_in
  11. GROUP BY vw_dt_start.id_comp, vw_dt_start.dt_out

Читателю предлагается самостоятельно решить эту задачу без использования представлений (т.е. построить решение в виде единственного оператора SELECT).

Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INFORMATION_SCHEMA INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker Больше тэгов
Учебник обновлялся
несколько дней назад
Воронеж ветеринарная клиника
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.