Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.10.2009, 15:10   #21
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

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

ну и раз ты все уже и сам знаешь, то дерзай
soleil@mmc вне форума Ответить с цитированием
Старый 27.10.2009, 15:41   #22
reBOOK
Пользователь
 
Аватар для reBOOK
 
Регистрация: 27.10.2009
Сообщений: 24
По умолчанию

Цитата:
Сообщение от soleil@mmc Посмотреть сообщение
дату нужно обрезать только в условии фильтрации чтобы найти все прокаты, которые были в указанном периоде

ну и раз ты все уже и сам знаешь, то дерзай
вот такой вот код у меня получился:

Код:
select prokat.code_c code_c, sum((prokat.endd-prokat.startt)*prokat.sbor) sbor
into t1
from prokat
where  prokat.startt > '01.04.01'
    and prokat.endd < '30.04.01';

select prokat.code_c code_c, sum(('30.04.01'-prokat.startt)*prokat.sbor) sbor
into t1
from prokat
where  prokat.startt > '01.04.01'
    and prokat.startt < '30.04.01'
    and prokat.endd > '30.04.01';

select prokat.code_c code_c, sum((prokat.endd-'01.04.01')*prokat.sbor) sbor
into t1
from prokat
where  prokat.startt < '01.04.01'
    and prokat.endd < '30.04.01'
    and prokat.endd > '01.04.01';

select prokat.code_c, '30' sbor
from prokat
into t1
where  prokat.startt < '01.04.01'
    and prokat.endd > '30.04.01';

select cinema.name name, sum(sbor) sbor
from t1, cinema
where cinema.code_c = t1.code_c;
опять же, ругается на into...

Последний раз редактировалось reBOOK; 27.10.2009 в 15:49.
reBOOK вне форума Ответить с цитированием
Старый 27.10.2009, 16:29   #23
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

покумекал я тут и вот такой запрос слабал

З.Ы.: в условии задачи не сказано, но предполагается что в поле prokat.sbor указывается полная сумма за весь период проката

З.Ы.2: данные в датасете days в том же ИБ можно получить, например, через дополнительно оформленную ХП или через еще тройку параметров (в этом случае просто поменять все обращения к полям датасета days на параметры, хотя в ИБ параметры в шапке вроде как ваще не работают)

вся шапка с with актуальна для оркала/мсскл
для ИБ она не нужна и см. ЗЫ2
Код:
with 
  cinema as (
  select 'Cinema1' name, 1 code_c from dual union all
  select 'Cinema2', 2 from dual union all
  select 'Cinema3', 3 from dual union all
  select 'Cinema4', 4 from dual union all
  select 'Cinema5', 5 from dual
  ),
  prokat as (
  select 1 code_c, to_date('01.09.2009', 'DD.MM.YYYY') startt, to_date('27.10.2009', 'DD.MM.YYYY') endd, 100000 sbor from dual union all
  select 1, to_date('01.10.2008', 'DD.MM.YYYY'), to_date('27.10.2008', 'DD.MM.YYYY'), 200000 from dual union all
  select 2, to_date('01.08.2009', 'DD.MM.YYYY'), to_date('27.10.2009', 'DD.MM.YYYY'), 100000 from dual union all
  select 2, to_date('01.10.2008', 'DD.MM.YYYY'), to_date('27.10.2008', 'DD.MM.YYYY'), 200000 from dual union all
  select 3, to_date('01.07.2009', 'DD.MM.YYYY'), to_date('27.11.2009', 'DD.MM.YYYY'), 100000 from dual union all
  select 3, to_date('01.10.2008', 'DD.MM.YYYY'), to_date('27.10.2008', 'DD.MM.YYYY'), 200000 from dual union all
  select 4, to_date('01.11.2009', 'DD.MM.YYYY'), to_date('27.11.2009', 'DD.MM.YYYY'), 100000 from dual union all
  select 4, to_date('01.10.2008', 'DD.MM.YYYY'), to_date('27.10.2008', 'DD.MM.YYYY'), 300000 from dual union all
  select 5, to_date('10.10.2009', 'DD.MM.YYYY'), to_date('27.10.2009', 'DD.MM.YYYY'), 100000 from dual union all
  select 5, to_date('01.10.2008', 'DD.MM.YYYY'), to_date('27.10.2008', 'DD.MM.YYYY'), 200000 from dual union all
  select 3, to_date('01.10.2009', 'DD.MM.YYYY'), to_date('27.10.2009', 'DD.MM.YYYY'), 100000 from dual
  ),
  days as (
  select
    trunc(to_date(:p0, 'DD.MM.YYYY'), 'mm') date1,
    trunc(add_months(to_date(:p0, 'DD.MM.YYYY'), 1), 'mm') - 1 date2,
    trunc(add_months(to_date(:p0, 'DD.MM.YYYY'), 1), 'mm') - trunc(to_date(:p0, 'DD.MM.YYYY'), 'mm') diff
  from dual
  )
  
select 
  c.name, 
  round(sum(  
             (case
              when -- обе даты внутри периода
                   ((p.startt >= d.date1) and (p.startt <= d.date2)) and 
                   ((p.endd >= d.date1) and (p.endd <= d.date2)) then p.endd - p.startt + 1
              when -- обе даты снаружи
                   ((p.startt < d.date1) and (p.endd > d.date2)) then d.diff
              when -- одна из дат внутри: а) левая граница внутри
                   ((p.startt >= d.date1) and (p.startt < d.date2) and (p.endd > d.date2)) then d.date2 - p.startt + 1
              when -- одна из дат внутри: б) правая граница внутри
                   ((p.endd > d.date1) and (p.endd <= d.date2) and (p.startt < d.date1)) then p.endd - d.date1 + 1
              end / (p.endd - p.startt + 1)) * p.sbor), 2) amount
from 
  cinema c, 
  prokat p, 
  days d
where 0=0
  and c.code_c = p.code_c
  and (
       ((p.startt >= d.date1) and (p.startt <= d.date2))
    or ((p.endd >= d.date1) and (p.endd <= d.date2))
    or ((p.startt <= d.date1) and (p.endd >= d.date2))
      )
group by c.name
order by c.name
soleil@mmc вне форума Ответить с цитированием
Старый 27.10.2009, 16:55   #24
reBOOK
Пользователь
 
Аватар для reBOOK
 
Регистрация: 27.10.2009
Сообщений: 24
По умолчанию

soleil@mmc спасибо, счас протестирую...

апд
к первому ЗЫ: я тоже в начале так подумал, но все таки в prokat.sbor указывается сбор за день проката, и поэтому код такой получился:
Код:
select c.name, sum(
             (case
              when ((p.startt >= '01.04.01') and (p.startt <= '30.04.01')) and
                   ((p.endd >= '01.04.01') and (p.endd <= '30.04.01')) then p.endd - p.startt + 1
              when ((p.startt < '01.04.01') and (p.endd > '30.04.01')) then '30'
              when ((p.startt >= '01.04.01') and (p.startt < '30.04.01') and (p.endd > '30.04.01')) then '30.04.01' - p.startt + 1
              when ((p.endd > '01.04.01') and (p.endd <= '30.04.01') and (p.startt < '01.04.01')) then p.endd - '01.04.01' + 1
              ) * p.sbor) amount
from
  cinema c,
  prokat p,
  days d
where c.code_c = p.code_c
   and (
       ((p.startt >= '01.04.01') and (p.startt <= '30.04.01'))
    or ((p.endd >= '01.04.01') and (p.endd <= '30.04.01'))
    or ((p.startt <= '01.04.01') and (p.endd >= '30.04.01'))
      )
group by c.name
order by c.name
хотя не уверен что можно проводить такие операции: "p.endd - '01.04.01' + 1"

и счас пишет ошибку Token unknow when...

Последний раз редактировалось reBOOK; 27.10.2009 в 17:22.
reBOOK вне форума Ответить с цитированием
Старый 27.10.2009, 17:25   #25
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

да ладно тебе
в ИБ case точно есть
небось со скобками напутал
soleil@mmc вне форума Ответить с цитированием
Старый 27.10.2009, 17:40   #26
reBOOK
Пользователь
 
Аватар для reBOOK
 
Регистрация: 27.10.2009
Сообщений: 24
По умолчанию

Цитата:
Сообщение от soleil@mmc Посмотреть сообщение
да ладно тебе
в ИБ case точно есть
небось со скобками напутал
вот и я сижу репу чешу...не в первой такая ошибка... вроде и по синтаксису правильно применено...

ладно, спасибо еще раз, уверен что код работает правильно, буду разбиратся со своим ib...
reBOOK вне форума Ответить с цитированием
Старый 30.10.2009, 18:00   #27
reBOOK
Пользователь
 
Аватар для reBOOK
 
Регистрация: 27.10.2009
Сообщений: 24
По умолчанию

решил сделать с view,получилось так
Код:
Create view t2 (code_c, days)
as
 select cast(code_c as integer), cast((prokat.endd-prokat.startt+1) as integer) days
 from prokat
 where prokat.startt < '30.04.01' and
       prokat.endd < '30.04.01' and
       prokat.startt > '01.04.01' and
       prokat.endd > '01.04.01'
UNION
  select cast(code_c as integer), cast((extract(day from prokat.endd)) as integer) days
  from prokat
  where prokat.endd > '01.04.01' and
        prokat.endd < '30.04.01' and
        prokat.startt < '01.04.01'
UNION
 select cast(code_c as integer), cast((31- (extract(day from prokat.startt))) as integer)days
 from prokat
 where prokat.endd > '30.04.01' and
       prokat.startt > '01.04.01' and
       prokat.startt < '30.04.01'
UNION
 select cast(code_c as integer), cast(30 as integer) days
 from prokat
 where prokat.startt < '01.04.01' and
       prokat.endd > '30.04.01';
ЗЫ. не могу править свое сообщение(наверно изза динамического ip)...сорри за дабл)

можно закрывать тему ...

Последний раз редактировалось reBOOK; 31.10.2009 в 16:13.
reBOOK вне форума Ответить с цитированием
Старый 11.11.2009, 10:07   #28
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

нда....
вместо union неплохо бы использовать union all
а вот мой код хотя бы обладает универсальностью чего не скажешь о твоем
как минимум, даже для такой финальной реализации можно было бы слабать селективную ХП, в которую параметрами передавать даты (а лучше всего одну дату, на основании которой вычислять первое и последнее число месяца и общее кол-во дней, и их потом подставлять в запросы)

З.Ы.: и чо - каждый день проката приходило одинаковое число зрителей?

Последний раз редактировалось soleil@mmc; 11.11.2009 в 13:28.
soleil@mmc вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запрос Dawystrik SQL, базы данных 1 20.09.2009 20:39
Запрос Ruska882009 Помощь студентам 2 25.02.2009 03:02
Запрос White БД в Delphi 0 18.09.2008 09:30
запрос ссылается на несвязанный с ним запрос kolebatel SQL, базы данных 0 11.06.2008 12:50