-
Notifications
You must be signed in to change notification settings - Fork 0
лабораторная работа 4 #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| --Лабораторная работа 4. | ||
| --Для выполнения данной лабораторной работы необходимо установить подключение к БД dbSQL | ||
| --ВНИМАНИЕ: Вычисляемые столбцы должны иметь соответствующие наименования. | ||
| --Фильтрация должна выполняться на исходных столбцах (не на вычисляемых). | ||
| --Задание 1. Запросы с группировкой | ||
| --1. Выведите номер заказа и количество в нем продуктов со скидкой (используйте filter). | ||
| select o.orderid, count(d.productid) filter (where discount>0) | ||
| from "Sales"."Orders" as o | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| group by o.orderid; | ||
| --2. Сформируйте выборку следующего вида: | ||
| select companyname, categoryname, count(p.productid) as count_products, avg(p.unitprice::numeric)::money, max(p.unitprice),min(p.unitprice) | ||
| from "Production"."Suppliers" as s | ||
| left join "Production"."Products" as p on s.supplierid = p.supplierid | ||
| join "Production"."Categories" as cat on p.categoryid = cat.categoryid | ||
| group by companyname, categoryname | ||
| having count(p.productid)>2; | ||
| --Выборка должна содержать информацию о поставщиках, которые поставляют более 2-х продуктов в каждой категории, а также максимальную, минимальную и среднюю цену поставляемых ими продуктов | ||
| --3. Сформируйте выборку следующего вида: | ||
| select split_part(companyname, ' ', 2), extract (YEAR from o.orderdate),count(distinct o.orderid), sum(d.unitprice * d.qty),count(distinct d.productid), count(d.unitprice) filter (where discount>0) | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| where o.orderdate between '20060101'::date and '20061231'::date | ||
| group by c.custid, EXTRACT(YEAR FROM o.orderdate) | ||
| order by sum(d.unitprice * d.qty ) desc limit 5; | ||
| --PS: в задании указано учитывать скидку, в примере она не учитывается - сделал как в примере. | ||
| --Выборка должна содержать информацию о 5 самых выгодных заказчиках, с точки зрения суммарной стоимости (с учетом скидки) сделанных ими заказов в 2006. | ||
| --4. Выведите количество заказов в разрезе стран и в разрезе городов. Представьте два варианта: | ||
| --a. Первый вариант решения должен содержать количество заказов только по странам и только по городам, | ||
| --а также общее количество заказов | ||
| select shipcountry,shipcity, count(distinct orderid) | ||
| from "Sales"."Orders" as o | ||
| group by rollup(shipcountry, shipcity) | ||
| --b. Второй вариант – все возможные итоги (итог по стране, итог по городу, итог по стране и городу, общий итог). | ||
| select shipcountry,shipcity, count(distinct orderid) | ||
| from "Sales"."Orders" as o | ||
| group by cube(shipcountry, shipcity); | ||
| --* Используйте соответствующее расширение GROUP BY (GROUPING SETS, CUBE, ROLLUP) | ||
| --5. Сформируйте выборку следующего вида: | ||
| -- select split_part(companyname, ' ', 2), extract (YEAR from o.orderdate),count(distinct o.orderid), sum(d.unitprice * d.qty),count(distinct d.productid), count(d.unitprice) filter (where discount>0) | ||
| select split_part(companyname, ' ', 2), concat(c.country,', ',city) as ad, concat(c.country,', ',city) as shipad, sum(d.unitprice * d.qty*(1-d.discount)) | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| where o.orderdate between '20070301'::date and '20070630'::date and country = shipcountry and city=shipcity and country in ('Brazil','Canada') | ||
| group by c.companyname, | ||
| c.country, | ||
| c.city, | ||
| o.shipcountry, | ||
| o.shipcity | ||
| order by sum(d.unitprice * d.qty*(1-d.discount)); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| --Выборка должна содержать информацию о Заказчиках из Бразилии и Канады, которые сделали заказы весной 2007 года, при этом адрес доставки должен совпадать с адресом Заказчика (под адресом подразумевается страна и город). | ||
| --Столбец «Сумма заказов с учетом скидки» должен содержать общую стоимость заказов конкретного заказчика за указанный период | ||
| --Задание 2. Использование оконных функций | ||
| --1. Сформируйте выборку, следующего вида: | ||
| -- | ||
| --Выборка должна выводить данные о заказах оформленных в сентябре 2006 года. Детали каждого заказа должны | ||
| --быть проранжированы в соответствие с их стоимостью. | ||
| select split_part(companyname, ' ', 2),o.orderid, d.productid, d.unitprice, d.qty, | ||
| (d.unitprice * d.qty * (1 - d.discount))::money as "Line Total", | ||
| sum(d.unitprice * d.qty * (1 - d.discount)) over(partition by o.orderid), | ||
| DENSE_RANK() OVER (PARTITION BY o.orderid ORDER BY d.unitprice * d.qty * (1 - d.discount) DESC) as "Line Rank" | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| WHERE o.orderdate BETWEEN '2006-09-01'::date AND '2006-09-30'::date | ||
| order by o.orderid,c.companyname; | ||
| --2. Выведите список заказчиков, проранжировав их в пределах каждой страны отдельно в порядке убывания общей стоимости сделанных заказчиком заказов. | ||
| --Результирующая выборка должна содержать только строки со значением ранга не более 2 | ||
| select * | ||
| from (select c.custid, companyname,c.country, | ||
| sum(d.unitprice * d.qty * (1 - d.discount)) | ||
| , DENSE_RANK() OVER (PARTITION BY c.country ORDER BY sum(d.unitprice * d.qty * (1 - d.discount)) desc) | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| group by c.custid | ||
| order by c.country,dense_rank) | ||
| where dense_rank<=2; | ||
| --3. Выведите для каждого продукта его название, цену по каталогу, количество заказов, в | ||
| -- которых данный продукт встречается, и ранг, в соответствии с частотой его присутствия в заказах | ||
| select | ||
| p.productname, | ||
| p.unitprice, | ||
| count(d.orderid) as qwt, | ||
| dense_rank() over( order by count(orderid) desc, p.productname asc) | ||
| from "Production"."Products" as p | ||
| join "Sales"."OrderDetails" as d on p.productid = d.productid | ||
| group by p.productname,p.unitprice; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2.3. Запрос не выводит товары, которые не входят ни в один заказ. |
||
| --4. Выведите одним запросом: номер заказчика, номер заказа, дату заказа, стоимость заказа, | ||
| --стоимость заказа за предыдущую дату по данному заказчику, разницу между стоимостью текущего заказа и предыдущего. | ||
| -- Null значения должны быть заменены 0. | ||
| --При расчете стоимости заказа необходимо учитывать скидку | ||
| select | ||
| c.custid, | ||
| o.orderid, | ||
| o.orderdate, | ||
| sum(d.unitprice * d.qty * (1 - d.discount)) | ||
| , (lag(sum(d.unitprice * d.qty * (1 - d.discount))::numeric,1,0) over(order by c.custid, o.orderid, o.orderdate))::money | ||
| , sum(d.unitprice * d.qty * (1 - d.discount))-(lag(sum(d.unitprice * d.qty * (1 - d.discount))::numeric,1,0) over(order by c.custid, o.orderid, o.orderdate))::money | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| group by c.custid,o.orderid; | ||
| --5. Выведите для всех заказов номер заказчика, номер заказа, дату заказа, объем заказа, процентную долю от общей | ||
| --стоимости всех заказов данного заказчика, нарастающий итог по заказам каждого заказчика. | ||
| select | ||
| c.custid, | ||
| o.orderid, | ||
| o.orderdate, | ||
| sum(d.unitprice * d.qty * (1 - d.discount)), | ||
| sum(d.unitprice * d.qty * (1 - d.discount))/sum(sum(d.unitprice * d.qty * (1 - d.discount))) over (partition by c.custid)*100, | ||
| sum(sum(d.unitprice * d.qty * (1 - d.discount))) over (partition by c.custid order by o.orderid) | ||
| from "Sales"."Customers" as c | ||
| join "Sales"."Orders" as o on c.custid=o.custid | ||
| join "Sales"."OrderDetails" as d on o.orderid=d.orderid | ||
| group by c.custid,o.orderid; | ||
| --6. Выведите для всех заказов, сделанных в 2007 году, название месяца, общий объем заказов в этом месяце, средний объем за 3 месяца (2 предыдущих и текущий) и нарастающий итого по месяцам. Воспользуйтесь представлением public."OrderValues" | ||
| SELECT | ||
| TO_CHAR(orderdate, 'Month') as monthname, | ||
| sum("OrderTotal") as order_count, | ||
| AVG(sum("OrderTotal")) OVER ( | ||
| ORDER BY EXTRACT(MONTH FROM orderdate) | ||
| ROWS BETWEEN 2 PRECEDING AND CURRENT ROW | ||
| ) as avg_last_3_months, | ||
| sum(sum("OrderTotal")) OVER ( | ||
| ORDER BY EXTRACT(MONTH FROM orderdate)) | ||
| FROM public."OrderValues" as o | ||
| WHERE orderdate BETWEEN '2007-01-01'::date AND '2007-12-31'::date | ||
| GROUP BY TO_CHAR(orderdate, 'Month'), EXTRACT(MONTH FROM orderdate) | ||
| ORDER BY EXTRACT(MONTH FROM orderdate); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2.6. Не ошибка, а замечание: правильнее создать алиас для EXTRACT(MONTH FROM orderdate) и не вычислять каждый раз, а сортировать по алиасу. |
||
| --7. Выведите выборку, содержащую ФИО сотрудника магазина, год и месяц, когда он оформлял заказы, стоимость оформленных в конкретном месяце заказов, стоимость оформленных в конкретном году заказов, нарастающий итог по месяцам в каждом году для каждого сотрудника и Общий итог по всем заказам оформленным конкретным сотрудником. | ||
| select | ||
| concat(lastname,' ',firstname), | ||
| extract(year from orderdate), | ||
| extract(month from orderdate), | ||
| sum("OrderTotal")::money, | ||
| sum(sum("OrderTotal")) over(partition by concat(lastname,' ',firstname),extract(year from orderdate)), | ||
| sum(sum("OrderTotal")) over(partition by concat(lastname,' ',firstname), | ||
| extract(year from orderdate) order by concat(lastname,' ',firstname),extract(year from orderdate),extract(month from orderdate)), | ||
| sum(sum("OrderTotal")) over(partition by concat(lastname,' ',firstname)) | ||
| from "HR"."Employees" as e | ||
| join public."OrderValues" as o on e.empid = o.empid | ||
| group by concat(lastname,' ',firstname), | ||
| extract(year from orderdate), | ||
| extract(month from orderdate) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4.a. 0
Не выводится количество заказов по городам.