Помогите с запросом, так называемый like for like
Необходимо рассчитать сумму продаж за 2 разных периода используя данные одной и той же таблицы
Вот то что у меня есть сейчас
Код:
Select * from (Select cc.tree||' '||cc.name as grp, sum(s.totalprice) as tp, l.name as nm,sum(period2.totpr) as tp3
from smdocuments d,
smspec s,
smcard c,
sacardclass cc,
smstorelocations l,
(Select cc2.tree||' '||cc2.name as grp2, sum(s2.totalprice) as totpr, l2.name nm2
from smdocuments d2,
smspec s2,
smcard c2,
sacardclass cc2,
smstorelocations l2
where d2.id = s2.docid
and d2.doctype = s2.doctype
and d2.doctype = 'CS'
and c2.article = s2.article
and c2.idclass = cc2.id
and l2.id = d2.locationfrom
and d2.createdat between to_date('&Период2_С', 'dd.mm.yyyy') and
to_date('&Период2_По', 'dd.mm.yyyy')
group by cc2.tree||' '||cc2.name,l2.name) period2
where d.id = s.docid
and d.doctype = s.doctype
and d.doctype = 'CS'
and c.article = s.article
and c.idclass = cc.id
and l.id = d.locationfrom
and period2.nm2 = l.name
and l.name in '&Место_хранения'
and period2.grp2 = cc.tree || ' ' || cc.name
and d.createdat between to_date('&Период1_С', 'dd.mm.yyyy') and
to_date('&Период1_По', 'dd.mm.yyyy')
group by cc.tree || ' ' || cc.name,l.name) pivot (sum(tp)/*,sum(tp3)*/ for nm in('&Место_хранения'))
если раскомментить строку работать не будет...я уже мозг сломал. надо чтобы сводная была по 2 суммам.ну и еще до кучи процентовка
Я не претендую на гурушность, но вложение в скобках не понимаю. На мой взгляд лучше расформировать вложенный запрос в условия ниже. Пока, благодаря форматированию, без поллитры понять с экрана, в чем проблема, затруднительно.
Вообще он занимается сведением всего в одну перекрестную таблицу
т.е вверху должно быть место хранения а сбоку группы товаров
ну и собсна по ним сумма за 2 периода.
сама логика запроса для pivot, по-моему, не подходит.
я по аналогии с вашим запросом сделала совсем простой - только выборку по артикулам (не по группам).
Получается - сколько периодов - столько union-ов.
В результате - кросс-таблица, строки - артикулы, столбцы - номера периодов (например, или диапазон в строку вывести можно),
на пересечении - сумма продаж.
Могут быть и другие варианты.
Но суть в том, что в результирующей выборке до pivot должна получится т.сказать "вертикалка" (в плане сумм) и доп. признак,
по которому можно определить, к которому периоду сумма относится, его и использовать в условии для pivot
Как-то так.
select * from
(select c.article, sum(s.totalprice) as sum_period, 1 as n_period
from supermag.smcard c,
supermag.smspec s,
supermag.smdocuments d
where c.accepted = 1
and c.article = s.article
and s.doctype= 'CS'
and s.doctype = d.doctype
and s.docid = d.id
and d.locationfrom in (2, 5)
and d.createdat between to_date('01.07.2012', 'dd.mm.yyyy')
and to_date('05.07.2012', 'dd.mm.yyyy')
group by c.article
union
select c.article, sum(s.totalprice) as sum_period, 2 as n_period
from supermag.smcard c,
supermag.smspec s,
supermag.smdocuments d
where c.accepted = 1
and c.article = s.article
and s.doctype= 'CS'
and s.doctype = d.doctype
and s.docid = d.id
and d.locationfrom in (2, 5)
and d.createdat between to_date('01.08.2012', 'dd.mm.yyyy')
and to_date('05.08.2012', 'dd.mm.yyyy')
group by c.article
)
pivot (sum(sum_period) for n_period in (1, 2))
если опять же по моему примеру, то, напрмер, так
select a.*, decode(nvl(a.period_1,0), 0, 0, round((nvl(a.period_2, 0)/a.period_1 ) * 100, 2))
from
(select * from
(select c.article, sum(s.totalprice) as sum_period, 1 as n_period
from supermag.smcard c,
supermag.smspec s,
supermag.smdocuments d
where c.accepted = 1
and c.article = s.article
and s.doctype= 'CS'
and s.doctype = d.doctype
and s.docid = d.id
and d.locationfrom in (2, 5)
and d.createdat between to_date('01.07.2012', 'dd.mm.yyyy')
and to_date('05.07.2012', 'dd.mm.yyyy')
group by c.article
union
select c.article, sum(s.totalprice) as sum_period, 2 as n_period
from supermag.smcard c,
supermag.smspec s,
supermag.smdocuments d
where c.accepted = 1
and c.article = s.article
and s.doctype= 'CS'
and s.doctype = d.doctype
and s.docid = d.id
and d.locationfrom in (2, 5)
and d.createdat between to_date('01.08.2012', 'dd.mm.yyyy')
and to_date('05.08.2012', 'dd.mm.yyyy')
group by c.article
)
pivot (sum(sum_period) for n_period in (1 as period_1, 2 as period_2))
) a
вот здесь хорошо показано с примерами:
Мне любопытно, что по скорости работы получится на больших БД в таком случае.
Вообще я сейчас думаю использовать with,
чтобы по месту хранения два периода брались и процетовка.
Так то жесть. Наверное воспользовавшись каким-нить построителем кубов было бы проще
Получиться должно чет вроде