Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопросы по Select  [new]
Phoenix28d
Member

Откуда:
Сообщений: 6
Дана таблица:

create table dbo.statistics 
(login    varchar(64),
send_date date, 
sms_cnt   int )


Нужно написать запрос, возвращающий для каждого логина минимальную дату,
когда количество сообщений было максимально, и максимальную дату, когда количество сообщений было минимально, а также количество сообщений.

Ожидаемый результат:
| login | min_date | max_sms_cnt | max_date |min_sms_cnt |
+-------+----------+-------------+----------+------------+
|login1 | 20150411 | 15154       | 20151012 | 10         |
|login2 | 20150301 | 20          | 20160513 | 8          |


Мой запрос, правильно ли:

select 
      [login], min(send_date) mindate, max(sms_cnt) maxcnt,
      max(send_date) maxdate, min(sms_cnt) mincnt
from [dbo].[statistics] (nolock)

Если неправильно помогите пжл с запросами как правильно)
10 дек 17, 10:13    [21021520]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
aleks222
Guest
select *
  from ( select distinct login from dbo.statistics ) as l
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt desc, send_date asc ) as max
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt asc, send_date desc ) as min
;
10 дек 17, 11:07    [21021550]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
aleks222
Guest
Впрочем, канешно, еще можно тряхнуть стариной...

коррелированный запрос:

min (max пишется онологично)
select * from dbo.[statistics] as s where sms_cnt = (select min(sms_cnt) from dbo.[statistics] where [login] = s.[login] )
                                          and send_date = (select max(send_date) from dbo.[statistics] where [login] = s.[login] and sms_cnt = s.sms_cnt )


Но это выносит мозг современным кнопкодавам.
10 дек 17, 11:19    [21021562]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
Phoenix28d
Member

Откуда:
Сообщений: 6
aleks222
select *
  from ( select distinct login from dbo.statistics ) as l
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt desc, send_date asc ) as max
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt asc, send_date desc ) as min
;


Минимальную дату неправильно находить
10 дек 17, 12:00    [21021585]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
Phoenix28d
Минимальную дату неправильно находить

RLY? Вариант, что вы неправильно сформулировали задачу, и потому написанный для вас запрос выдает некорректный результат, в вашу светлую голову не пришел?
11 дек 17, 11:45    [21023528]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5151
aleks222
select *
  from ( select distinct login from dbo.statistics ) as l
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt desc, send_date asc ) as max
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt asc, send_date desc ) as min
;
Зачем два self join если можно одним проходом?

select login,
       max(case when rn1 = 1 then send_date end) min_date,
       max(case when rn1 = 1 then sms_cnt end) max_sms_cnt,
       max(case when rn2 = 1 then send_date end) max_date,
       max(case when rn2 = 1 then sms_cnt end) min_sms_cnt
  from (select row_number() over (partition by login order by sms_cnt desc, send_date asc) rn1,
               row_number() over (partition by login order by sms_cnt asc, send_date desc) rn2,
               s0.*
          from statistics s0) s1
 where 1 in (rn1, rn2)
group by login

+ в Oracle это просто группировка + keep
select login,
       min(send_date) keep (dense_rank first order by sms_cnt desc) min_date,
       max(sms_cnt) max_sms_cnt,
       max(send_date) keep (dense_rank first order by sms_cnt asc) max_date,
       min(sms_cnt) minax_sms_cnt
  from statistics
group by login
11 дек 17, 16:13    [21024560]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
aleks222
Guest
dbms_photoshop
aleks222
select *
  from ( select distinct login from dbo.statistics ) as l
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt desc, send_date asc ) as max
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt asc, send_date desc ) as min
;
Зачем два self join если можно одним проходом?

select login,
       max(case when rn1 = 1 then send_date end) min_date,
       max(case when rn1 = 1 then sms_cnt end) max_sms_cnt,
       max(case when rn2 = 1 then send_date end) max_date,
       max(case when rn2 = 1 then sms_cnt end) min_sms_cnt
  from (select row_number() over (partition by login order by sms_cnt desc, send_date asc) rn1,
               row_number() over (partition by login order by sms_cnt asc, send_date desc) rn2,
               s0.*
          from statistics s0) s1
 where 1 in (rn1, rn2)
group by login

+ в Oracle это просто группировка + keep
select login,
       min(send_date) keep (dense_rank first order by sms_cnt desc) min_date,
       max(sms_cnt) max_sms_cnt,
       max(send_date) keep (dense_rank first order by sms_cnt asc) max_date,
       min(sms_cnt) minax_sms_cnt
  from statistics
group by login


Затем, страдалец, что реальные посоны не лопатят фсю таблу по каждому поводу.
Редко, панимашь, кому надобен весь список гопом.
А два join дают индексам шанс.
11 дек 17, 16:44    [21024694]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5151
aleks222,

То есть было сделано предположение про
1) низкую кардинальность login
2) высокую кардинальность send_date, sms_cnt в рамках login
3) наличие необходимых индексов

PS. На оракловом форуме есть один у которого все чудаки, а у тебя страдальцы.
Не совсем понятно зачем так выпячивать свои психологические травмы.
11 дек 17, 17:00    [21024754]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
aleks222
Guest
dbms_photoshop,

Я бы на тебя посмотрел, если бы тебя чмырили всю юность, псехолог блин.
11 дек 17, 17:39    [21024870]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 53662
dbms_photoshop,

ты тоже начал в mssql переезжать?
или уже давно?
11 дек 17, 18:05    [21024959]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5151
andreymx,

Я с него начинал и никуда не уходил.
11 дек 17, 18:35    [21025035]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
Phoenix28d
Member

Откуда:
Сообщений: 6
Phoenix28d
aleks222
select *
  from ( select distinct login from dbo.statistics ) as l
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt desc, send_date asc ) as max
         outer apply( select top(1) * from  dbo.statistics where login = l. login order by sms_cnt asc, send_date desc ) as min
;


Минимальную дату неправильно находить


Извиняюсь ваш ответ правильно находить, спасибо
12 дек 17, 12:50    [21026830]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по Select  [new]
Добрый Э - Эх
Guest
dbms_photoshop
PS. На оракловом форуме есть один у которого все чудаки
это тонкий намек на Elic-а ???
14 дек 17, 12:21    [21033206]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить