Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 200 additions & 0 deletions hws/hw4.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
--1.Выведите самые дорогие продукты в каждой категории. Детали должны присутствовать!
--Решите данную задачу с использованием:
--a.вложенного подзапроса
--
select p.productname, p.categoryid, p.unitprice
from "Production"."Products" p
join (
select categoryid, max(unitprice) as max_price
from "Production"."Products"
group by categoryid
) m using (categoryid)
where p.unitprice = m.max_price;
--
--
--b.коррелированного подзапроса
--
select p.productname, p.categoryid, p.unitprice
from "Production"."Products" p
where p.unitprice = (
select max(p2.unitprice)
from "Production"."Products" p2
where p2.categoryid = p.categoryid
);

--UPD

--c. оконной функции
select productname, categoryid, unitprice
from (
select
p.productname,
p.categoryid,
p.unitprice,
max(p.unitprice) over (partition by p.categoryid) as max_price
from "Production"."Products" p
) t
where t.unitprice = t.max_price;

--UPD

--2.Выведите код заказчика, год заказа, ранг по каждому заказчику в каждом году в соответствии с
--общей стоимостью заказа (OrderTotal) и стоимость заказа. В выборке должны присутствовать только
--записи с рангом 1 и 2. Воспользуйтесь представлением public."OrderValues"
select r.custid, r."Year", r."Rank", r."OrderTotal"
from (
select
ov.custid,
extract(year from ov.orderdate)::int as "Year",
ov."OrderTotal",
rank() over (partition by ov.custid, extract(year from ov.orderdate) order by ov."OrderTotal" desc) as "Rank"
from public."OrderValues" ov
) as r
where r."Rank" in (1, 2)
order by r.custid, r."Year", r."Rank";
--


--3.Выведите информацию о заказчиках, за исключением тех, кто купил менее 30 наименований продуктов.
--
select c.custid, c.companyname, c.contacttitle
from "Sales"."Customers" c
where c.custid in (
select o.custid
from "Sales"."Orders" o
join "Sales"."OrderDetails" od on od.orderid = o.orderid
group by o.custid
having count(distinct od.productid) >= 30
);
--
--
--4.Используя запрос к таблице Продуктов сформируйте выборку следующего вида:
--Для формирования значений в столбцах Category Name и AveragePrice (средняя цена продуктов по категории) используйте коррелированные подзапросы.
--Выборка должна включать только те товары, цена которых выше средней по категории.
--
select
p.productname,
p.unitprice,
(select c.categoryname
from "Production"."Categories" c
where c.categoryid = p.categoryid) as "CategoryName",
(select avg(p2.unitprice::numeric)::money
from "Production"."Products" p2
where p2.categoryid = p.categoryid) as "AveragePrice"
from "Production"."Products" p
where p.unitprice::numeric > (
select avg(p2.unitprice::numeric)
from "Production"."Products" p2
where p2.categoryid = p.categoryid
);
--
--
-- 5.Выведите список товаров, цена которых выше средней цены по категории.
-- Для формирования столбцов categoryname и avg_unitprice используйте коррелированные подзапросы
select
p.productname,
p.unitprice,
(select c.categoryname
from "Production"."Categories" c
where c.categoryid = p.categoryid ) as "CategoryName",
(select avg(p2.unitprice::numeric)::money
from "Production"."Products" p2
where p2.categoryid = p.categoryid) as "AveragePrice"
from "Production"."Products" p
where p.unitprice::numeric > (
select avg(p2.unitprice::numeric)
from "Production"."Products" p2
where p2.categoryid = p.categoryid
);
--
--
--6.Сформируйте выборку следующего вида:
--Выборка должна содержать только те записи, в которых стоимость заказов, сделанных конкретным заказчиком за самый первый год,
--когда он делал заказы (first-year) не превышает стоимость заказов за последующие года. То есть, разница (diff) между стоимостью заказов текущего года и
--заказов за первый год меньше нуля.
--
with yearly as (
select
o.custid,
extract(year from o.orderdate)::int as order_year,
sum( (od.unitprice::numeric) * od.qty * (1 - od.discount) ) as year_total_num
from "Sales"."Orders" o
join "Sales"."OrderDetails" od using (orderid)
group by o.custid, extract(year from o.orderdate)
),
first_year as (
select custid, min(order_year) as first_year
from yearly
group by custid
),
fy_tot as (
select y.custid, y.order_year, y.year_total_num
from yearly y
)
select
y.custid,
c.companyname,
y.order_year as year,
(y.year_total_num)::money as ord_total,
(fy.year_total_num)::money as "first-year",
case
when (y.year_total_num - fy.year_total_num) < 0
then '(' || to_char(abs(y.year_total_num - fy.year_total_num),
'LFM$999G999G990D00') || ')'
else to_char(y.year_total_num - fy.year_total_num,
'LFM$999G999G990D00')
end as diff
from yearly y
join first_year f
on f.custid = y.custid
join fy_tot fy
on fy.custid = y.custid
and fy.order_year = f.first_year
join "Sales"."Customers" c
on c.custid = y.custid
where y.order_year <> f.first_year
and y.year_total_num - fy.year_total_num < 0
order by y.custid, y.order_year;
--
--
--7.Выведите следующую информацию о заказчиках и количестве сделанных ими заказов. Решите данную задачу 2 способами:
--a.Используя коррелированный подзапрос
--
select
c.companyname,
c.country,
(
select count(*)
from "Sales"."Orders" o
where o.custid = c.custid
) as orders_count
from "Sales"."Customers" c;
--
--
--b.Используя подзапрос LATERAL
--
select
c.companyname,
c.country,
co.orders_count
from "Sales"."Customers" c
left join lateral (
select count(*) as orders_count
from "Sales"."Orders" o
where o.custid = c.custid
) co on true;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Не увидела решение =(

-- UPD

-- 8
-- Запрос с помощью рекурсии поэлементно обходит массив символов и на каждом шаге формирует строку, постепенно
-- собирая фразу Hello, world!.
-- выводится:
-- H
-- He
-- Hel
-- Hell
-- Hello
-- и так далее до Hello, world!

-- UPD