Re[7]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 15.10.10 19:38
Оценка: +1
Здравствуйте, Sinix, Вы писали:

_FR>>И как OVER PARTITION BY поможет посчитать FIRST / LAST?

S>Пардон, пропустил про требование портируемости для оракла. С кастомным агрегатом ValueForMin всё было бы просто.

Да не, это я не сразу сообразил, что это было к вопросу о возможности создания собственного агрегата — но ведь всё равно не получится, ибо стандартные агрегаты имеют заранее известный тип результата, а мне нужны агрегаты, тип которых определяется типом параметра.
Help will always be given at Hogwarts to those who ask for it.
Re: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 11:13
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Имеется некая табличка, к которой обращаются с запросами. В запросах имееюся некая группировка и выборка значений. Например:

_FR>
CREATE TABLE [#T] (
  [Number] int,
  [DateTime] datetime,
  [Value] nchar, /* <--- еггог :) */
);


_FR>Требуется уметь считать по [Value] не только стандартные COUNT/AVG/SUM/MIN/MAX но, например, и FIRST и LAST — то есть в пределах группы требуется найти строку с минимальным или максимальным значением [DateTime] и вернуть значение [Value] этой строки.

Я в таких случаях делаю так:
SELECT TOP 1
    [Value]
FROM    #T
ORDER BY [DateTime] DESC
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[2]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 11:21
Оценка:
Да... если группировка, то подзапросом.


CREATE TABLE [#T] (
  NumberMy /* лень везде писать []*/ int,
  DateTimeMy datetime,
  ValueMy NCHAR(64),
  GroupMy int 
);

SELECT 
    GroupMy
    ,(    SELECT TOP 1 
            t_.ValueMy
          FROM    #T AS t_
          WHERE    t_.GroupMy = t.GroupMy
          ORDER BY DateTimeMy)
FROM #T AS t
GROUP BY    
    GroupMy


SELECT *
FROM
    #T AS t
INNER JOIN
    (    SELECT  
            DateTimeMax = MAX(t_.DateTimeMy)
        FROM    #T AS t_
        GROUP BY t_.GroupMy     
    ) AS td
ON    t.DateTimeMy = td.DateTimeMax


Лучше способ мне не известен.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[3]: [MSSQL] Агрегаты FIRST и LAST
От: Sinix  
Дата: 16.10.10 12:27
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

ZAM>Лучше способ мне не известен.

CROSS APPLY?

Кроме +1 к ЧСВ (ух ты, удалось найти применение и этой фиговине) конечно ничего не даёт.
Re[3]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 13:53
Оценка:
Здравствуйте, _FRED_, Вы писали:

S>>P.S. Использовать зарезервированные кейворды для идентефикаторов — зло:)

_FR>Мне больше импонирует понятность и очевидность идентификаторов, нежели их кейвордность. Именно поэтому я использую [] для всех идентификаторов, а не только там, где приходится.
Хм... а как искать поля в запросе? -- Допустим есть у меня поле [from] (ну вот там мыло хранится, к примеру: {from, to, datetime, text}). Запрос большой и не везде имя со скобками [] написано. Реальная ситуация что без []: торопился когда писал, или писал разгильдяй какой-то (обычно ж с БД команда работает). И вот надо найти место, где пишутся данные в [from] и поправить баг. Как мне искать это поле в запросе??? Я пока не видел тулзы, которая бы эту проблему решала: т.е. прыгнула в редакторе на нужное место чтоб я его поправить мог. А если таблицу, например, так спроектировать {fromMy, toMy, at, textMy} то поиск поля в запросе будет легко осущестляться по {Ctrl+F}. Уж лучше я буду в имени писать в коннце My (хотя toMy это и правда глаз режет) и экономить время при сопровождении кода, чем радоваться какой у меня нириально очевидный код.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[4]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 15:45
Оценка:
Здравствуйте, Sinix, Вы писали:

ZAM>>Лучше способ мне не известен.

S>CROSS APPLY?;)

S>Кроме +1 к ЧСВ (ух ты, удалось найти применение и этой фиговине) конечно ничего не даёт.

:-D

Вообще, у меня такая же проблема сейчас и записаей уже 100 миллиардов :). Я подумываю или делать метки в важных местах. Т.е. что-то вроде этого:
CREATE TABLE [#T] (
  ...
  ,TagDayBeg bit NOT NULL /* или так */
  ,DayBeg DATETIME NULL /* или так */
);

А в процедуре, пихающей данные в таблицу соответственно проставлять эти метки. Если метки в индекс сунуть, то поиск должен быстрее быть.

Или делать таблицы меток, как-то так:
CREATE TABLE [Log] (
  At datetime PRIMARY KEY NOT NULL,
  ValueMy NCHAR(64) NOT NULL,
  GroupMy int 
);

CREATE TABLE [LogTags] (
  At datetime NOT NULL,
  TypeMy CHAR(3) NOT NULL,
  GroupMy int 
);


В LogTags.TypeMy будет писаться тип помеченного события. Возможно и словарь типов событий буит.
Например, последняя за опр день запись LogImportantEvents.TypeMy = 'LD', в процедуре добавления записи в лог, заодно обновляю и запись в LogTags.
INSERT INTO Log
...

UPDATE LogTags SET 
    At = @At
WHERE
    TypeMy = 'LD'
    AND GroupMy = @Group
    AND At BETWEEN dbo.DTBegDay(@At) AND dbo.DTEndDay(@At)

IF @@ROWCOUNT = 0
    INSERT INTO LogTags
    ...


Таблица LogTags должна получиться намного меньше самого Log, поля At и Type индексированны. Значит вставка/обновление должно быть моментальным. Вообще таблица меток мне нравится больше, т.к. можно много чего в ней наотмечать.

Идеи такие. Надо поиграться, подумать...
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[5]: [MSSQL] Агрегаты FIRST и LAST
От: Sinix  
Дата: 16.10.10 15:54
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

ZAM>Здравствуйте, Sinix, Вы писали:


ZAM>>>Лучше способ мне не известен.

S>>CROSS APPLY?

S>>Кроме +1 к ЧСВ (ух ты, удалось найти применение и этой фиговине) конечно ничего не даёт.

ZAM>:-D

ZAM>Вообще, у меня такая же проблема сейчас и записаей уже 100 миллиардов . Я подумываю или делать метки в важных местах. Т.е. что-то вроде этого:[sql]


ZAM>А в процедуре, пихающей данные в таблицу соответственно проставлять эти метки. Если метки в индекс сунуть, то поиск должен быстрее быть.

Можно, но лучше сделать ч/з тригеры.
Re[4]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 16.10.10 16:09
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

S>>>P.S. Использовать зарезервированные кейворды для идентефикаторов — зло

_FR>>Мне больше импонирует понятность и очевидность идентификаторов, нежели их кейвордность. Именно поэтому я использую [] для всех идентификаторов, а не только там, где приходится.
ZAM>Хм... а как искать поля в запросе? -- Допустим есть у меня поле [from] (ну вот там мыло хранится, к примеру: {from, to, datetime, text}). Запрос большой и не везде имя со скобками [] написано. Реальная ситуация что без []: торопился когда писал, или писал разгильдяй какой-то (обычно ж с БД команда работает).

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

ZAM>И вот надо найти место, где пишутся данные в [from] и поправить баг. Как мне искать это поле в запросе???


В том, что касается именно "from", всё очень просто: такой запрос просо напросто сам не выполнится, если я правильно понимаю. Поэтому отыскать места, где данное слово не заэскейпино проблем не составляет.

ZAM>Я пока не видел тулзы, которая бы эту проблему решала: т.е. прыгнула в редакторе на нужное место чтоб я его поправить мог. А если таблицу, например, так спроектировать {fromMy, toMy, at, textMy} то поиск поля в запросе будет легко осущестляться по {Ctrl+F}. Уж лучше я буду в имени писать в коннце My (хотя toMy это и правда глаз режет) и экономить время при сопровождении кода, чем радоваться какой у меня нириально очевидный код.


Что-то я совершенно не понял проблемы, которая вас смущает.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 16.10.10 16:11
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

_FR>>Имеется некая табличка, к которой обращаются с запросами. В запросах имееюся некая группировка и выборка значений. Например:

ZAM>CREATE TABLE [#T] (
ZAM>  [Number] int,
ZAM>  [DateTime] datetime,
ZAM>  [Value] nchar, /* <--- еггог :) */
ZAM>);


Про какую ошибку вы говорите? В моём запросе нет ни одной синтаксической ошибки

_FR>>Требуется уметь считать по [Value] не только стандартные COUNT/AVG/SUM/MIN/MAX но, например, и FIRST и LAST — то есть в пределах группы требуется найти строку с минимальным или максимальным значением [DateTime] и вернуть значение [Value] этой строки.

ZAM>Я в таких случаях делаю так:
ZAM>SELECT TOP 1
ZAM>    [Value]
ZAM>FROM    #T
ZAM>ORDER BY [DateTime] DESC


Можно посмотреть полный текст запроса, который вы "в таких случаях делаете так", как показали? Ибо то, что возвращает ваш запрос не имеет никакого отношения к тому, что возвращает мой.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 16.10.10 17:10
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

ZAM>Да... если группировка, то подзапросом.

ZAM>CREATE TABLE [#T] (
ZAM>  NumberMy /* лень везде писать []*/ int,
ZAM>  DateTimeMy datetime,
ZAM>  ValueMy NCHAR(64),
ZAM>  GroupMy int 
ZAM>);

ZAM>SELECT 
ZAM>    GroupMy
ZAM>    ,(    SELECT TOP 1 
ZAM>            t_.ValueMy
ZAM>          FROM    #T AS t_
ZAM>          WHERE    t_.GroupMy = t.GroupMy
ZAM>          ORDER BY DateTimeMy)
ZAM>FROM #T AS t
ZAM>GROUP BY    
ZAM>    GroupMy


ZAM>SELECT *
ZAM>FROM
ZAM>    #T AS t
ZAM>INNER JOIN
ZAM>    (    SELECT  
ZAM>            DateTimeMax = MAX(t_.DateTimeMy)
ZAM>        FROM    #T AS t_
ZAM>        GROUP BY t_.GroupMy     
ZAM>    ) AS td
ZAM>ON    t.DateTimeMy = td.DateTimeMax

ZAM>Лучше способ мне не известен.

Это разве именно то, что мне нужно? Где группировка по месяцу ичто такое "GroupMy"
Help will always be given at Hogwarts to those who ask for it.
Re[4]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 21:11
Оценка: 24 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>Это разве именно то, что мне нужно? Где группировка по месяцу ичто такое "GroupMy" :xz:

GroupMy — это поле, по которому группировать. У тебя это "MONTH([DateTime]) [Month]". Я плохо прочёл твоё сообщение, увидел что надо по группам максимумы брать вот про это и расплылся мыслью.

если с месяцем, примерно так:
SELECT 
     [Number] 
    ,MONTH(t.[DateTime]) [Month]
    ,(    SELECT TOP 1 
            t_.[Value]
          FROM    #T AS t_
          WHERE    MONTH(t_.[DateTime])= MONTH(t.[DateTime])
          ORDER BY t_.[DateTime])
FROM #T AS t
GROUP BY
    [Number]
    ,MONTH(t.[DateTime])


PS: ничего, что я на "ты"?
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[5]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 21:14
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Разгильдяйство потому так и нгазывается, что из-за него случаются различного вида траблы, так чему же удивляться-то :xz: У меня _таких_ траблов не случается вообще.

*абсолютно без сарказма* Очень завидую тому, с какими ответственными людьми тебе приходится работать. Я уже давно устал бить всех по рукам.

ZAM>>И вот надо найти место, где пишутся данные в [from] и поправить баг. Как мне искать это поле в запросе???

_FR>В том, что касается именно "from", всё очень просто: такой запрос просо напросто сам не выполнится, если я правильно понимаю. Поэтому отыскать места, где данное слово не заэскейпино проблем не составляет.
Да, ты прав, с "from" не заработает без []. Плохой пример. Вот посмотри: "text", "int" и т.д. всё работает, только что проверил. Если у тебя не работает, то я хочу на вашу планету. :)

_FR>Что-то я совершенно не понял проблемы, которая вас смущает.

Проблема: как найти идентификатор, если он совпадает с ключевым словом и при этом парсер "понимает" его правильно без []. И вокруг разгильдяи, им лень писать всё с [], и им нельзя настучать по рукам. И код большой, и ключевое слово часто в коде встречается, и время поджимает, и нервы на пределе, и система уже сдана и работает.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[6]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 17.10.10 06:04
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

_FR>>Разгильдяйство потому так и нгазывается, что из-за него случаются различного вида траблы, так чему же удивляться-то У меня _таких_ траблов не случается вообще.

ZAM>*абсолютно без сарказма* Очень завидую тому, с какими ответственными людьми тебе приходится работать. Я уже давно устал бить всех по рукам.

Я говорил только за себя А всё остальное, как обнаружилось, требуется исправить.

ZAM>>>И вот надо найти место, где пишутся данные в [from] и поправить баг. Как мне искать это поле в запросе???

_FR>>В том, что касается именно "from", всё очень просто: такой запрос просо напросто сам не выполнится, если я правильно понимаю. Поэтому отыскать места, где данное слово не заэскейпино проблем не составляет.
ZAM>Да, ты прав, с "from" не заработает без []. Плохой пример. Вот посмотри: "text", "int" и т.д. всё работает, только что проверил. Если у тебя не работает, то я хочу на вашу планету.

_FR>>Что-то я совершенно не понял проблемы, которая вас смущает.

ZAM>Проблема: как найти идентификатор, если он совпадает с ключевым словом и при этом парсер "понимает" его правильно без []. И вокруг разгильдяи, им лень писать всё с [], и им нельзя настучать по рукам. И код большой, и ключевое слово часто в коде встречается, и время поджимает, и нервы на пределе, и система уже сдана и работает.

Это очень просто: идентификатор принадлежит какому-то другому объекту (например, имя колонки без имени таблицы не употребляется). Проблема явно высосана из пальца.
Help will always be given at Hogwarts to those who ask for it.
Re[5]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 17.10.10 06:38
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

_FR>>Это разве именно то, что мне нужно? Где группировка по месяцу ичто такое "GroupMy"

ZAM>GroupMy — это поле, по которому группировать. У тебя это "MONTH([DateTime]) [Month]". Я плохо прочёл твоё сообщение, увидел что надо по группам максимумы брать вот про это и расплылся мыслью.

ZAM>если с месяцем, примерно так:

ZAM>SELECT 
ZAM>     [Number] 
ZAM>    ,MONTH(t.[DateTime]) [Month]
ZAM>    ,(    SELECT TOP 1 
ZAM>            t_.[Value]
ZAM>          FROM    #T AS t_
ZAM>          WHERE    MONTH(t_.[DateTime])= MONTH(t.[DateTime])
ZAM>          ORDER BY t_.[DateTime])
ZAM>FROM #T AS t
ZAM>GROUP BY
ZAM>    [Number]
ZAM>    ,MONTH(t.[DateTime])


Ага, спасибо. В таком виде возвращает то же, что и мои запросы:
SELECT [Number], MONTH([DateTime]) [Month],
  (SELECT TOP(1) [Value]
   FROM #T X
   WHERE [Number] = T.[Number] AND MONTH([DateTime]) = MONTH(T.[DateTime])
   ORDER BY [DateTime] DESC, [Value] ASC) [Value]
FROM #T T
GROUP BY [Number], MONTH([DateTime]);


ZAM>PS: ничего, что я на "ты"?


Конечно нет. Надеюсь мои "выкания" не очень мешают
Help will always be given at Hogwarts to those who ask for it.
Re[7]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 17.10.10 18:28
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Я говорил только за себя ;) А всё остальное, как обнаружилось, требуется исправить.

А я говорил за реальную жизнь. Если за себя, то просто писать код быстрее с постфиксом коротким, чем вечно мизинцами на [] тыкать, а на очевидность, лично для меня, это не влияет. На этом, предлагаю разойтись на свои баррикады. Если желаешь, давай откроем ветку отдельную, и подиспутируем.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[3]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 17.10.10 18:32
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Про какую ошибку вы говорите? В моём запросе нет ни одной синтаксической ошибки :no:

Как же ты всётаки любишь запрещённые приёмы...

CREATE TABLE [#T] (
  [Number] int,
  [DateTime] datetime,
/*             |
               |
               V  */
  [Value] nchar,--<<-----<<<
/*             ^
               |
               |  */

);

Так видно?
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[4]: [MSSQL] Агрегаты FIRST и LAST
От: _FRED_ Черногория
Дата: 18.10.10 08:24
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

_FR>>Про какую ошибку вы говорите? В моём запросе нет ни одной синтаксической ошибки

ZAM>Как же ты всётаки любишь запрещённые приёмы...
ZAM>CREATE TABLE [#T] (
ZAM>  [Number] int,
ZAM>  [DateTime] datetime,
ZAM>/*             |
ZAM>               |
ZAM>               V  */
ZAM>  [Value] nchar,--<<-----<<<
ZAM>/*             ^
ZAM>               |
ZAM>               |  */

ZAM>);

ZAM>Так видно?

Запятую-то видно было ещё в первом сообщениию. Ошибки не видно
Help will always be given at Hogwarts to those who ask for it.
Re[5]: [MSSQL] Агрегаты FIRST и LAST
От: ZAMUNDA Земля для жалоб и предложений
Дата: 18.10.10 10:52
Оценка:
Здравствуйте, _FRED_, Вы писали:
_FR>Запятую-то видно было ещё в первом сообщениию. Ошибки не видно :)
Но студия без SP, ругнулась: и правильно кстати... Ибо сказано в писании:
CREATE TABLE table_name 
   ( { < column_definition > | < table_constraint > } [ ,...n ] 
   )


Так что ошибка-то есть, просто студия такие косяки пропускает. А ты сам говорил, что если неправильно, то надо поправить и не вожно что работает. С собой-то ты спорить не будешь!
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.