powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Интересная задача, споткнулся с case-ом, help
12 сообщений из 12, страница 1 из 1
Интересная задача, споткнулся с case-ом, help
    #39362963
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Используя входные данные провести ABC анализ для всех позиций в разрезе Год (YEAR), STORE_FORMAT, CATEGORY используя показатель оборот в рублях, оборот в штуках, поделив на 3 категории:
85 % - A
10 % - B
5 % - C
:Должно получиться вроде этого
Код: plsql
1.
2.
3.
Year  | Store_format      | Category                      |Product        |   ABC_QNTY   |  ABC_RUB
2015  | Большой магазин   |  Игрушки для мальчиков        |    Халк       |        B     |      B
2016  | Маленький магазин |  Энергетические напитки       |    Заря       |        A     |      B




Мой запрос на данный момент выглядит так:
:запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Select month, store_format, category, s.product
,case 
	when sales_qnty/sum(sales_qnty)*100 between 85 and 100  then 'A'
	when sales_qnty/sum(sales_qnty)*100 between 5 and 10  then 'B'
	when sales_qnty/sum(sales_qnty)*100 between 0 and 5  then 'C'
end as ABC_QNTY
,case
	when price/sum(price*sales_qnty)*100 between 85 and 100 then 'A'
	when price/sum(price*sales_qnty)*100  between 5 and 10 then 'B'
	when price/sum(price*sales_qnty)*100  between 0 and 5 then 'C'
end as ABC_RUB
from sale s 
join sprav sp ON sp.product=s.product
group by month, store_format,category,s.product,sales_qnty,price



У меня сомнения на счет того, что я верно действую в операторе case . И не переборщил ли я с группировкой? Быть может кто подскажет как такую задачу решить другим путем? Не исключаю, что мой вариант - ахинея) Помогите плиз люди бывалые!

P.S. исходные данные таблиц прикрепил во вложении.
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363038
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Rust_CohleУ меня сомнения на счет того, что я верно действую в операторе case .
Правильные сомнения. Разумнее создать таблицу соответствия процент-категория.

Rust_Cohleне переборщил ли я с группировкой?Переборщил... теоретически ты можешь получить в запросе несколько полностью идентичных строк, что для группировки в общем странно... убери оттуда последние 2 поля. Или строго обоснуй их присутствие там.
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363224
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaРазумнее создать таблицу соответствия процент-категория.
Подскажите пожалуйста поподробнее, как это делается. Пока непонятно(

AkinaПереборщил... теоретически ты можешь получить в запросе несколько полностью идентичных строк, что для группировки в общем странно... убери оттуда последние 2 поля. Или строго обоснуй их присутствие там.
А если я уберу из группировки последние 2 поля, то запрос сразу сломается. Я ведь в кейсе использую их оба, и скорее всего неверно. Ошибка что то вроде - данные поля не используются ни 1 в агрегатной функции. Как обойти этот момент правильной реализацией?
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363449
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрел ещё раз. Попристальнее. Ваще бред оказался.

Во-первых, выпал диапазон от 10 до 85 процентов. Совсем.
Во-вторых, расчёт процента-то идёт от общей суммы. Т.е. имеем два уровня группировки - сумма по группе и сумма отдельной записи. В рамках одного запроса это не реализуется - т.е. должен быть подзапрос, считающий итоговые суммы:
Код: sql
1.
2.
3.
SELECT d.group_fields, SUM(d.price_field) total_price
FROM data_table d
GROUP BY d.group_fields

его связываем с основным и считаем проценты:
Код: sql
1.
2.
3.
SELECT dt.group_fields, dt.price_field/sq.total_price percent
FROM datatable dt, (subquery code) sq
WHERE dt.group_fields = sq.group_fields
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363451
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну а кейс уже как-нить самостоятельно прикрути.
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363658
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а еще совсем нубский вопрос)
как мне из поля month содержащие значения вида (201501, 201602) корректно вернуть только год?Тут же нет разделителей, цельный интежер. Не оракловыми средствами.
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363708
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Rust_Cohle , LEFT(month,4)
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363713
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Спасибо, вы просто бог sql-я!)
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363730
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina Rust_Cohle , LEFT(month,4)
Тогда возникает следующий вопрос - как далее проводить группировку дабы все 201501 и 201502 попали в одну группу.
По синониму же это делать нельзя.
Код: sql
1.
2.
3.
Select LEFT(month,4) as YEAR,...
....
group by YEAR
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39363741
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Rust_CohleПо синониму же это делать нельзя.
В mysql можно.

В других СУБД - по тому же самому выражению
Код: sql
1.
group by LEFT(month,4)
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39364064
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaВо-вторых, расчёт процента-то идёт от общей суммы. Т.е. имеем два уровня группировки - сумма по группе и сумма отдельной записи. В рамках одного запроса это не реализуется - т.е. должен быть подзапрос, считающий итоговые суммы:
Код: sql
1.
2.
3.
SELECT d.group_fields, SUM(d.price_field) total_price
FROM data_table d
GROUP BY d.group_fields

его связываем с основным и считаем проценты:
Код: sql
1.
2.
3.
SELECT dt.group_fields, dt.price_field/sq.total_price percent
FROM datatable dt, (subquery code) sq
WHERE dt.group_fields = sq.group_fields



Блин чёт не соображу как доварить этот запрос. У меня выходит вот что:
: беда
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Select LEFT(month,4) as year, s.store_format, sp.category, s.product
,case 
	when (sales_qnty/total_kolvo)*100 between 85 and 100  then 'A'
	when (sales_qnty/total_kolvo)*100 between 50 and 84  then 'B'
	when (sales_qnty/total_kolvo)*100 between 0 and 5  then 'C'
end as ABC_QNTY
,case
	when (price/total_sum)*100 between 85 and 100 then 'A'
	when (price/total_sum)*100  between 5 and 10 then 'B'
	when (price/total_sum)*100  between 0 and 5 then 'C'
end as ABC_RUB
from sale s
,(Select LEFT(month,4) as year, store_format, category, t2.product, sum(sales_qnty) as total_kolvo, sum(price*sales_qnty) as total_sum
 from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category,t2.product) as sq
 ,sprav sp 
where sq.product=s.product and sp.product=s.product
group by LEFT(month,4), s.store_format,sp.category,s.product



Я может неверно делаю этот подзапрос. Куда его надо запихнуть? И могу ли я, указав синонимы, использовать их для деления в кейсе? При выполнении ругается так - Столбец "sale.SALES_QNTY" недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.
Столбец "sq.total_kolvo" недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.
...
Рейтинг: 0 / 0
Интересная задача, споткнулся с case-ом, help
    #39364373
Rust_Cohle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понял, что группировка по оборотам должна быть на уровень выше, то есть не включая конкретный продукт. Попытался этот подзапрос запихнуть в КЕЙС. Но все равно неправильно. Ошибка следующего вида.
Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения.
: Запрос_обновленный
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Select LEFT(month,4) as year, s.store_format, sp.category, s.product
,case 
	when (sum(sales_qnty)/(Select sum(sales_qnty) as total_kolvo from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 85 and 100  then 'A'
	when (sum(sales_qnty)/(Select sum(sales_qnty) as total_kolvo from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 5 and 10  then 'B'
	when (sum(sales_qnty)/(Select sum(sales_qnty) as total_kolvo from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 0 and 5  then 'C'
end as ABC_QNTY
,case
	when (sum(price)/(Select sum(price*sales_qnty) as total_sum from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 85 and 100 then 'A'
	when (sum(price)/(Select sum(price*sales_qnty) as total_sum from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 5 and 85 then 'B'
	when (sum(price)/(Select sum(price*sales_qnty) as total_sum from sale t1 join sprav t2 ON t1.product=t2.product
  group by LEFT(month,4), store_format,category))*100 between 0 and 5 then 'C'
end as ABC_RUB
from sale s
 ,sprav sp 
where sp.product=s.product
group by LEFT(month,4), s.store_format,sp.category,s.product


...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Интересная задача, споткнулся с case-ом, help
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]