Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сделать запрос без подзапросов / 22 сообщений из 22, страница 1 из 1
04.08.2021, 23:10
    #40088746
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table customers(
Id bigint,
FIO nvarchar(100)
)


create table orders(
Id bigint,
CustomerId bigint,
ProductID bigint,
Qty bigint,
Date datetime
)




Нужно получить всех кастомеров, кто за прошлый год сделал более 5 заказов. Как это сделать в один SELECT, без подзапросов?
...
Рейтинг: 0 / 0
05.08.2021, 02:03
    #40088751
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Это задача аналогична задаче на поиск дублей. Стандартная задача для студентов, а так же на собеседованиях (приходится вспоминать, и ведь всерьёз спрашивают!).

На будущее. Хорошим тоном является написание не только скрипта по созданию таблиц и других объектов, но и заполнению их тестовыми данными. Тогда куда как выше вероятность, что вам станут помогать.

И да, элементарная вежливость так же помогает. Она в общем-то даже где-то как-то обязательна... К людям надо как-то обратиться. Например "уважаемые будущие коллеги". Если вам от них что-то нужно, то нужно это у них... попросить! При том явным образом. Например: "помогите пжлст".

Ничего и близкого мы у вас не видим... :(

Поэтому можно сказать, что я вам помогаю авансом.


Код: sql
1.
2.
3.
4.
5.
6.
7.
insert into #orders (id, CustomerId)
 values (1, 1),(2, 1),(3, 1),(4, 1),(5, 1),(6, 1),(7, 2) ;

select CustomerId, count(Id)
from #orders
group by CustomerId
having count(Id) >= 5 ;
...
Рейтинг: 0 / 0
05.08.2021, 08:43
    #40088766
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь
приходится вспоминать
Ну ладно, вспоминать count и having :-)

Кесарь
И да, элементарная вежливость так же помогает. Она в общем-то даже где-то как-то обязательна... К людям надо как-то обратиться. Например "уважаемые будущие коллеги". Если вам от них что-то нужно, то нужно это у них... попросить! При том явным образом. Например: "помогите пжлст".
Будущие менеджеры не просят, они дают задания!
...
Рейтинг: 0 / 0
05.08.2021, 09:33
    #40088771
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь,

За внимание спасибо, но я не случайно сказал про получение ФИО(блин, сперва написал про ФИО, а потом как-то стерлось), а не CustomerID - такую элементарщину я ам могу изобразить влет. Как мне с ФИО быть без подзапросов, подскажите?
...
Рейтинг: 0 / 0
05.08.2021, 09:39
    #40088773
HandKot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
Кесарь,

За внимание спасибо, но я не случайно сказал про получение ФИО, а не CustomerID - такую элементарщину я ам могу изобразить влет. Как мне с ФИО быть без подзапросов, подскажите?

Код: sql
1.
2.
3.
join customers c on c.Id  = o.CustomerId 
group by FIO 
...
...
Рейтинг: 0 / 0
05.08.2021, 09:44
    #40088775
Посетитель
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
HandKot,

и схолпнете полных тёзок
группировку по customerid нельзя убирать
...
Рейтинг: 0 / 0
05.08.2021, 11:19
    #40088805
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Посетитель,

Да, Вы абсолютно правы - тезки не должны мешаться и путать выборку.
...
Рейтинг: 0 / 0
05.08.2021, 11:24
    #40088808
Посетитель
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin,

так в чем проблема?
поправить вариант, предложенный HandKot, не составляет никакого труда, надо просто вернуть CustomerId в group by

хотя, требование делать без подзапросов в данном случае противоречит здравому смыслу.
...
Рейтинг: 0 / 0
05.08.2021, 11:31
    #40088811
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
Кесарь,

За внимание спасибо, но я не случайно сказал про получение ФИО(блин, сперва написал про ФИО, а потом как-то стерлось), а не CustomerID - такую элементарщину я ам могу изобразить влет. Как мне с ФИО быть без подзапросов, подскажите?



Это всё элементарщина. Может вам всё таки начать учить то, что вам нужно сдавать?


Код: sql
1.
2.
3.
4.
5.
select c.FIO, c.Id, count(o.Id)
from #orders o
  join #customers c on c.Id = o.CustomerId
group by c.FIO, c.Id
having count(o.Id) >= 5 ;
...
Рейтинг: 0 / 0
05.08.2021, 11:39
    #40088817
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
А без ненужной группировки по FIO можно обойтись?
...
Рейтинг: 0 / 0
05.08.2021, 11:40
    #40088820
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
alexeyvg
Кесарь
приходится вспоминать
Ну ладно, вспоминать count и having :-)


Ну вот как-то так случилось, что приходилось гнаться за скоростью, а having работает уже на последнем этапе, после сбора всех данных и группировок. И фактически в рабочем коде этот оператор не был использован не только мною, но и другими коллегами, вообще ни разу. Поэтому про него и не сразу вспоминаешь, когда начинают задавать вопросы для вчерашних студентов.


Будущие менеджеры не просят, они дают задания!

Очень похоже на то :)
...
Рейтинг: 0 / 0
05.08.2021, 11:47
    #40088823
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
А без ненужной группировки по FIO можно обойтись?


Да, сделать отбор по группировке (первый мой запрос) в cte, а потом уже к ней присоединять таблицу покупателей.
...
Рейтинг: 0 / 0
05.08.2021, 11:56
    #40088829
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь,

А это (через CTE) будет эффктивнее, чем с подзапросом?
...
Рейтинг: 0 / 0
05.08.2021, 12:41
    #40088858
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
Кесарь,

А это (через CTE) будет эффктивнее, чем с подзапросом?


А вот чтобы это узнать, надо запустить оба варианта на реальных данных и посмотреть план запроса. Как смотреть план запроса, можно ознакомится в разных видео и статьях.

Например такая поисковая строка дасть вам нужное: "Сергей Олонцев Как читать план запроса в SQL Server". Короче всё в ваших руках.
...
Рейтинг: 0 / 0
05.08.2021, 12:44
    #40088860
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь
savin
Кесарь,

А это (через CTE) будет эффктивнее, чем с подзапросом?


А вот чтобы это узнать, надо запустить оба варианта на реальных данных и посмотреть план запроса. Как смотреть план запроса, можно ознакомится в разных видео и статьях.

Например такая поисковая строка дасть вам нужное: "Сергей Олонцев Как читать план запроса в SQL Server". Короче всё в ваших руках.

Чтобы ЭТО узнать - надо читать совсем другие книжки.

ЗЫ. СТЕ ничего не меняет. Это только форма записи запроса.
...
Рейтинг: 0 / 0
05.08.2021, 12:44
    #40088861
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
А без ненужной группировки по FIO можно обойтись?
Зачем? это ещё одна вводная, меняете ТЗ на ходу? :-)

Посетитель
HandKot,

и схолпнете полных тёзок
группировку по customerid нельзя убирать
Понятно, в группировке должны быть и ИД, и ФИО, а в выводе только ФИО (правда, вывод одинаковых ФИО выглядит глупо, но учебное задание на то и учебное)
...
Рейтинг: 0 / 0
05.08.2021, 12:47
    #40088863
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь
alexeyvgНу ладно, вспоминать count и having :-)

Ну вот как-то так случилось, что приходилось гнаться за скоростью, а having работает уже на последнем этапе, после сбора всех данных и группировок. И фактически в рабочем коде этот оператор не был использован не только мною, но и другими коллегами, вообще ни разу. Поэтому про него и не сразу вспоминаешь, когда начинают задавать вопросы для вчерашних студентов.Мне тоже редко приходилось использовать, но если задача фильтровать по агрегатам, то как тут оптимизировать (если не хранить агрегаты)?
Всё равно считать и фильтровать, а хэвингом это будет, или ещё как то - вопрос десятый
...
Рейтинг: 0 / 0
05.08.2021, 12:47
    #40088864
Посетитель
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь,

вот только нет никакого оператора cte в плане запроса.
у
with cte as(select...)
select ...
from cte
будет такой же план, как и у
select...
from(select...) as cte
...
Рейтинг: 0 / 0
05.08.2021, 13:21
    #40088876
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Посетитель
Кесарь,

вот только нет никакого оператора cte в плане запроса.
у
with cte as(select...)
select ...
from cte
будет такой же план, как и у
select...
from(select...) as cte


И что? Я в курсе, что такое cte.

Тем не менее у двух запросов

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
;with cte as (
select o.CustomerId
from #orders o
group by o.CustomerId
having count(o.Id) >= 5 )
select c.*
from cte
  join #customers c on c.Id = cte.CustomerId

select c.*
from #orders o
  join #customers c on c.Id = o.CustomerId
group by c.FIO, c.Id
having count(o.Id) >= 5 ;



планы выполнения будут разными. А вот какой эффективнее, можно будет понять лишь на реальных данных (хотя первый с cte выглядит более лёгким, но это весьма предварительный результат).
...
Рейтинг: 0 / 0
05.08.2021, 13:25
    #40088877
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
Кесарь
Посетитель
Кесарь,

вот только нет никакого оператора cte в плане запроса.
у
with cte as(select...)
select ...
from cte
будет такой же план, как и у
select...
from(select...) as cte


И что? Я в курсе, что такое cte.

Тем не менее у двух запросов

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
;with cte as (
select o.CustomerId
from #orders o
group by o.CustomerId
having count(o.Id) >= 5 )
select c.*
from cte
  join #customers c on c.Id = cte.CustomerId

select c.*
from #orders o
  join #customers c on c.Id = o.CustomerId
group by c.FIO, c.Id
having count(o.Id) >= 5 ;




планы выполнения будут разными. А вот какой эффективнее, можно будет понять лишь на реальных данных (хотя первый с cte выглядит более лёгким, но это весьма предварительный результат).


Вопрос был про "подзапрос" vs "cte", какое отношение к нему имеет ваш второй select?
...
Рейтинг: 0 / 0
05.08.2021, 14:03
    #40088890
SQLIntento
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
savin
А без ненужной группировки по FIO можно обойтись?


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
drop table if exists #orders
go

drop table if exists #customers
go

create table #orders(id bigint, CustomerID bigint)
go

create table #customers(id bigint, FIO nvarchar(100))
go

insert into #customers (id, FIO)
 values (1, 'Иванов Иван Иванович'), (2, 'Петров Пётр Петрович'), (3, 'Иванов Иван Иванович')
go

insert into #orders (id, CustomerId)
 values (1, 1),(2, 1),(3, 1),(4, 1),(5, 1),(6, 1),(7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 3)
go

select max(c.FIO), c.Id, count(o.Id)
from #orders o
  join #customers c on c.Id = o.CustomerId
group by c.Id
having count(o.Id) >= 5
go
...
Рейтинг: 0 / 0
06.08.2021, 01:07
    #40089050
savin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сделать запрос без подзапросов
SQLIntento,

Супер! Спасибо.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сделать запрос без подзапросов / 22 сообщений из 22, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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