Size: a a a

SqlCom.ru - Стиль жизни SQL

2021 January 12

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
Лучший ник
То поставить with ties
смотря, что люди хотят)
Если строго 2 позиции, то точно без with ties
источник

Л

Лучший ник in SqlCom.ru - Стиль жизни SQL
Стиль жизни sql 🤟
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
Фулл задача:
Есть 3 таблицы::

- create table Orders (
- cust_id int,
- prod_id int,
- price bigint,
- quantity bigint,
- dat date
- )
- create Customers (
- FIO varchar(50),
- id int
- )
- create Products (
- product varchar(50),
- id int
- )

Нужно написать SQL-запрос, который выведет список из ФИО каждого покупателя и названий 2 товаров, на которые этот покупатель потратил больше всего денег в прошлом году

Вот что я сейчас написал:

with cte as (
select ROW_NUMBER() OVER(PARTITION BY cust_id ORDER BY cust_id, sum_ ),
      prod_id,
      sum(price * quantity) as sum_
from Orders
where YEAR(dat) = 2020
group by cust_id,prod_id
)

select Customers.FIO,
      Products.product
from cte
LEFT JOIN Customers ON cte.cust_id = Customers.cust_id
LEFT JOIN Products ON cte.prod_id = Products.prod_id
where cte.ROW_NUMBER <=2
источник
2021 January 13

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
PARTITION BY cust_id ORDER BY cust_id

не надо так=)
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
Andrew Komarov
PARTITION BY cust_id ORDER BY cust_id

не надо так=)
Если не трудно,объясни пжл , почему так нельзя ,либо можно ссылку на уроки и задачки на эту тему
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
впринципе,мне это и не нужно,можно просто
ROW_NUMBER() OVER(PARTITION BY cust_id ORDER BY  sum_ ),
?
источник

Л

Лучший ник in SqlCom.ru - Стиль жизни SQL
Посоветуйте пожалуйста хорошую книгу по T-SQL на русском или есои можно pdf сразу скиньте
источник

А

Андрій in SqlCom.ru - Стиль жизни SQL
Никита
Если не трудно,объясни пжл , почему так нельзя ,либо можно ссылку на уроки и задачки на эту тему
Потому что это поле в партишн- следовательно одинаковое для всего окна
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
Никита
впринципе,мне это и не нужно,можно просто
ROW_NUMBER() OVER(PARTITION BY cust_id ORDER BY  sum_ ),
?
PARTITION BY cust_id означает, что вы создали группу по cust_id и сортируете в переделах группы  cust_id по cust_id.

Вероятно оптимизатор не дурак, но зачем...
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
Андрій
Потому что это поле в партишн- следовательно одинаковое для всего окна
Да, так и понял,спасибо
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
Никита
впринципе,мне это и не нужно,можно просто
ROW_NUMBER() OVER(PARTITION BY cust_id ORDER BY  sum_ ),
?
если у вас будет три одинаковых суммы, то они в рандомном порядке будут. Но  возьмете вы потом два продукта.

Если хотите все три , то надо использовать DENSE_RANK ()
Если хотите два, но по какому-то приниципу, можно ордер баить по sum_  DESC (у вас слово деск пропущено, а по умолчанию ASC)  и чему-то еще, смотрите пример
источник

А

Андрій in SqlCom.ru - Стиль жизни SQL
Вот кстати вопрос, а если действительно пофиг на сортировку? Как лучше дошла, вписать поле по которому партиционировано?
Гдетот читал(кажется в exam refs 761) рекомендацию так не делать, и писать order by (Select NULL) чтобы явно указать что сортировка нас не интересует
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
Andrew Komarov
если у вас будет три одинаковых суммы, то они в рандомном порядке будут. Но  возьмете вы потом два продукта.

Если хотите все три , то надо использовать DENSE_RANK ()
Если хотите два, но по какому-то приниципу, можно ордер баить по sum_  DESC (у вас слово деск пропущено, а по умолчанию ASC)  и чему-то еще, смотрите пример
Если нужно будет выводить все значения , то запрос будет таким?:
with cte as (
select DENSE_RANK() OVER(PARTITION BY cust_id ORDER BY cust_id, sum_  DESC) as RANK,
      cust_id,
      prod_id,
      sum(price * quantity) as sum_
from Orders
where YEAR(dat) = 2020
group by cust_id,prod_id,RANK
)

select Customers.FIO,
      Products.product
from cte
LEFT JOIN Customers ON cte.cust_id = Customers.cust_id
LEFT JOIN Products ON cte.prod_id = Products.prod_id
where cte.RANK <=2
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
Андрій
Вот кстати вопрос, а если действительно пофиг на сортировку? Как лучше дошла, вписать поле по которому партиционировано?
Гдетот читал(кажется в exam refs 761) рекомендацию так не делать, и писать order by (Select NULL) чтобы явно указать что сортировка нас не интересует
order by (SELECT 1)
обычно так пишу)
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
Никита
Если нужно будет выводить все значения , то запрос будет таким?:
with cte as (
select DENSE_RANK() OVER(PARTITION BY cust_id ORDER BY cust_id, sum_  DESC) as RANK,
      cust_id,
      prod_id,
      sum(price * quantity) as sum_
from Orders
where YEAR(dat) = 2020
group by cust_id,prod_id,RANK
)

select Customers.FIO,
      Products.product
from cte
LEFT JOIN Customers ON cte.cust_id = Customers.cust_id
LEFT JOIN Products ON cte.prod_id = Products.prod_id
where cte.RANK <=2
SELECT
 c.FIO,
 p.product
 o.sm AS amount
FROM Customers c
INNER JOIN
(
 SELECT
   o.cust_id,
   o.prod_id,
   DENSE_RANK ()OVER (PARTITION BY o.cust_id ORDER BY o.sm DESC) rn
 FROM
 (
   SELECT
     o.cust_id,
     o.prod_id,
     SUM(price*quantity) sm
   FROM Orders o
   WHERE YEAR(o.dat) = 2020
   GROUP BY
     o.cust_id,
     o.prod_id
 )o  
)o
ON c.id = o.cust_id
INNER JOIN Products p
ON p.id = o.prod_id
WHERE o.rn<=2
источник

g

greeninsania in SqlCom.ru - Стиль жизни SQL
Использую
order by 1/0
источник

Н

Никита in SqlCom.ru - Стиль жизни SQL
Andrew Komarov
SELECT
 c.FIO,
 p.product
 o.sm AS amount
FROM Customers c
INNER JOIN
(
 SELECT
   o.cust_id,
   o.prod_id,
   DENSE_RANK ()OVER (PARTITION BY o.cust_id ORDER BY o.sm DESC) rn
 FROM
 (
   SELECT
     o.cust_id,
     o.prod_id,
     SUM(price*quantity) sm
   FROM Orders o
   WHERE YEAR(o.dat) = 2020
   GROUP BY
     o.cust_id,
     o.prod_id
 )o  
)o
ON c.id = o.cust_id
INNER JOIN Products p
ON p.id = o.prod_id
WHERE o.rn<=2
А join будет отрабатывать быстрее, чем with ... as?
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
greeninsania
Использую
order by 1/0
и получаете экзепшн?
источник

g

greeninsania in SqlCom.ru - Стиль жизни SQL
Andrew Komarov
и получаете экзепшн?
Неа, в ms sql в оконках работает))
источник

AK

Andrew Komarov in SqlCom.ru - Стиль жизни SQL
greeninsania
Неа, в ms sql в оконках работает))
деление на ноль работает?
источник