Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / TOP + ORDER BY / 25 сообщений из 26, страница 1 из 2
05.03.2013, 11:51
    #38174343
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
всё руки не доходили запостить, но
всплыл пару недель назад один из старых

У него перестал работать запрос, проблема оказалась в том, что если идёт присвоение переменной в запросе и стоит оператор order by, то присваивается только первая переменная. Если поставить top, то всё работает как надо

Вот тест кейс, коментим ТОП и смотрим результат.

Код: 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.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
declare @columnList nvarchar(max) = '';
declare @columnListOut nvarchar(max) = '';
declare @columnListBp nvarchar(max) = '';
declare @columnListBpOut nvarchar(max) = '';

with cte as
(
select '1.1.1' as QID union all
select '1.1.10' union all
select '5.5.21' union all
select '1.1.9' union all
select '1.1.2' union all
select '1.1.8'
  
)

--select * from cte;
select top 10000 
      @columnList = 
       @columnList +
       case 
        when @columnList = ''
        then ''
        else ',
        '
       end +  'max(case r.QID when ''' + c.QID + ''' then r.answer end) as "QID_' + c.QID + '"',
       
       @columnListOut = 
       @columnListOut +
       case 
        when @columnListOut = ''
        then ''
        else ',
        '
       end +  'c."QID_' + c.QID + '"',
       
       @columnListBp =  
       @columnListBp +
       case 
        when @columnList = '' --it is correct
        then ''
        else ',
        '
       end +  'max(case r.QID when ''' + c.QID + ''' then r.BP_ID end) as "BP_' + c.QID + '"',
       
       @columnListBpOut =  
       @columnListBpOut +
       case 
        when @columnList = ''  --it is correct
        then ''
        else ',
       '
       end +  'c."BP_' + c.QID + '"'
       
  from cte c
 where c.QID is not null
/*
Columns are ordered by name in alphabet order
*/
    --order by c.QID;
    order by 
    cast(left(c.QID, charindex('.', c.QID) -1) as int),
    cast(substring(c.QID, charindex('.', c.QID) + 1, LEN(c.QID) - charindex('.', reverse(c.QID)) - charindex('.', c.QID)) as int),
    cast(right(c.QID, charindex('.', reverse(c.QID)) - 1) as int);
    
    print --top 10 
       @columnList
...
Рейтинг: 0 / 0
05.03.2013, 11:53
    #38174348
pkarklin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
авторУ него перестал работать запрос

А кто-то обещал, что такой запрос впринципе должен работать так, как мы того ожидаем?
...
Рейтинг: 0 / 0
05.03.2013, 11:57
    #38174362
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
Банальная конкатенация строк.

set @v = @v + t.value

я как бы "ожидал". Причём без "оредер бай" работает. Либо с ТОП работает.
После добавление Ордер бай я бы ожидал "тот же результат с другим порядком".
...
Рейтинг: 0 / 0
05.03.2013, 11:59
    #38174367
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKя как бы "ожидал". Причём без "оредер бай" работает. Либо с ТОП работает.
После добавление Ордер бай я бы ожидал "тот же результат с другим порядком".
На чем основаны были ожидания ?
...
Рейтинг: 0 / 0
05.03.2013, 11:59
    #38174372
Гость333
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKБанальная конкатенация строк.

set @v = @v + t.value
В вашем примере не банальная конкатенация, а недокументированный приём. Нигде не зафиксировано, как это должно работать.
...
Рейтинг: 0 / 0
05.03.2013, 12:02
    #38174379
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
GloryNIIIKя как бы "ожидал". Причём без "оредер бай" работает. Либо с ТОП работает.
После добавление Ордер бай я бы ожидал "тот же результат с другим порядком".
На чем основаны были ожидания ?

На том что "без ордер бай работало, но нужно было плучить тот же результат только в другом порядке и том что ордер бай не изменяет количество строк, что кстати хорошо видно в подзапросах которые должны возврщать только одну строку).
...
Рейтинг: 0 / 0
05.03.2013, 12:03
    #38174381
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
Гость333NIIIKБанальная конкатенация строк.

set @v = @v + t.value
В вашем примере не банальная конкатенация, а недокументированный приём. Нигде не зафиксировано, как это должно работать.

Прям хакерский приём :) ?!
Я сейчас не про факт конкатенации говорю (хотя явно не в курсорах обычно реализуют её), а про количество строк.
...
Рейтинг: 0 / 0
05.03.2013, 12:04
    #38174382
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
Гость333NIIIKБанальная конкатенация строк.

set @v = @v + t.value
В вашем примере не банальная конкатенация, а недокументированный приём. Нигде не зафиксировано, как это должно работать.
+
это должно работать "одинаково" и нигде не зафиксировано что присваивание переменных в запросе делается "по первой строке если стоит ордер бай".
...
Рейтинг: 0 / 0
05.03.2013, 12:05
    #38174384
tpg
tpg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
...
Рейтинг: 0 / 0
05.03.2013, 12:08
    #38174390
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
tpg http://www.sql.ru/faq/faq_topic.aspx?fid=731

Для случая с группировкой я предпочитаю CLR функцию.
Тот метод кстати медленее работает. По быстродействую сопостовим "тупо написать отдельную функци делающую отдельный запрос и конкатенацию)" если не медленее.
...
Рейтинг: 0 / 0
05.03.2013, 12:10
    #38174392
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIK+
это должно работать "одинаково" и нигде не зафиксировано что присваивание переменных в запросе делается "по первой строке если стоит ордер бай".
BOL
SELECT @local_variable is typically used to return a single value into the variable. However, when expression is the name of a column, it can return multiple values. If the SELECT statement returns more than one value, the variable is assigned the last value that is returned .
...
Рейтинг: 0 / 0
05.03.2013, 12:11
    #38174393
daw
daw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
> это должно работать "одинаково"

это кто сказал?

> и нигде не зафиксировано что присваивание переменных в запросе делается "по первой строке если стоит ордер бай".

давно уж расписались в том, что результат запроса, подобного вашему неопределен.

http://support.microsoft.com/kb/287515/en-us
...
Рейтинг: 0 / 0
05.03.2013, 12:13
    #38174400
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKНа том что "без ордер бай работало, но нужно было плучить тот же результат только в другом порядке и том что ордер бай не изменяет количество строк, что кстати хорошо видно в подзапросах которые должны возврщать только одну строку).
Молодец.
...
Рейтинг: 0 / 0
05.03.2013, 12:17
    #38174405
Гость333
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKПрям хакерский приём :) ?!
Я сейчас не про факт конкатенации говорю (хотя явно не в курсорах обычно реализуют её), а про количество строк.
Недокументированный приём — это запрос вида
Код: sql
1.
2.
select @v = @v + t.value
from ...
...
Рейтинг: 0 / 0
05.03.2013, 12:39
    #38174452
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
GloryNIIIK+
это должно работать "одинаково" и нигде не зафиксировано что присваивание переменных в запросе делается "по первой строке если стоит ордер бай".
BOL
SELECT @local_variable is typically used to return a single value into the variable. However, when expression is the name of a column, it can return multiple values. If the SELECT statement returns more than one value, the variable is assigned the last value that is returned .

До "last value" оно и не дошло

Разницу вообще все без "top" и "заведомо большой Top" видят ?!
...
Рейтинг: 0 / 0
05.03.2013, 12:43
    #38174459
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKРазницу вообще все без "top" и "заведомо большой Top" видят ?!
Разницу между "я хочу, чтобы так работало" и "так работает" тоже кто-то видит ?
...
Рейтинг: 0 / 0
05.03.2013, 12:53
    #38174481
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
GloryNIIIKРазницу вообще все без "top" и "заведомо большой Top" видят ?!
Разницу между "я хочу, чтобы так работало" и "так работает" тоже кто-то видит ?

Вы эксперт местный или "адвокат майкрософта" ?!

Документация на оператор Топ есть? должен ли заведомо большой оператор топ изменять количество строк в запросе или результат запроса?
...
Рейтинг: 0 / 0
05.03.2013, 12:55
    #38174487
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKДокументация на оператор Топ есть?
А документация на select @v = @v + t.value есть ?

NIIIKдолжен ли заведомо большой оператор топ изменять количество строк в запросе или результат запроса?
Причем тут количество записей ?
Меняется план выполнения.
...
Рейтинг: 0 / 0
05.03.2013, 13:10
    #38174526
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
Код: sql
1.
2.
3.
4.
5.
    order by c.QID;
    /*order by 
    cast(left(c.QID, charindex('.', c.QID) -1) as int),
    cast(substring(c.QID, charindex('.', c.QID) + 1, LEN(c.QID) - charindex('.', reverse(c.QID)) - charindex('.', c.QID)) as int),
    cast(right(c.QID, charindex('.', reverse(c.QID)) - 1) as int);*/



такой вариант тоже работет, только порядок "алфавитный" (собственно его и фиксили).
...
Рейтинг: 0 / 0
05.03.2013, 13:15
    #38174533
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKУ него перестал работать запрос, проблема оказалась в том, что если идёт присвоение переменной в запросе и стоит оператор order by, то присваивается только первая переменная . Если поставить top, то всё работает как надо

Вот тест кейс, коментим ТОП и смотрим результат.
<...>

что-то не сходится с вашим утверждением
закомментил TOP, добавил вывод остальных трех переменных, на выходе
max(case r.QID when '5.5.21' then r.answer end) as "QID_5.5.21"
c."QID_5.5.21"
max(case r.QID when '5.5.21' then r.BP_ID end) as "BP_5.5.21"
c."BP_5.5.21"
т.е., все четыре переменных получают значения
...
Рейтинг: 0 / 0
05.03.2013, 13:21
    #38174546
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
ShakillNIIIKУ него перестал работать запрос, проблема оказалась в том, что если идёт присвоение переменной в запросе и стоит оператор order by, то присваивается только первая переменная . Если поставить top, то всё работает как надо

Вот тест кейс, коментим ТОП и смотрим результат.
<...>

что-то не сходится с вашим утверждением
закомментил TOP, добавил вывод остальных трех переменных, на выходе
max(case r.QID when '5.5.21' then r.answer end) as "QID_5.5.21"
c."QID_5.5.21"
max(case r.QID when '5.5.21' then r.BP_ID end) as "BP_5.5.21"
c."BP_5.5.21"
т.е., все четыре переменных получают значения

1) у меня тоже получается только последняя .
тут моя ошибка, я по запарке (и было не вчера) в голове отложил только как заказчик говорил
2) если стоит топ и ордер - возвращает ВСЕ записи
3) если только ордер (по цифрам) БЕЗ Топ - возвращает только первую запись
4) если стоит ордер БЕЗ топ, но по имени - возвращает все записи.
...
Рейтинг: 0 / 0
05.03.2013, 13:24
    #38174552
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIK1) у меня тоже получается только последняя .
тут моя ошибка, я по запарке (и было не вчера) в голове отложил только как заказчик говорил
2) если стоит топ и ордер - возвращает ВСЕ записи
3) если только ордер (по цифрам) БЕЗ Топ - возвращает только первую запись
4) если стоит ордер БЕЗ топ, но по имени - возвращает все записи.
Для неумеющих читать офф.ссылки

An examination of the SHOWPLAN output of the query reveals that the SQL Server query p rocessor builds an different execution plan when expressions are applied to columns in the query's ORDER BY clause, than when those same expressions are applied to columns in the query's SELECT list. The decision made by the query processor is based on the cost of possible execution plans .
...
Рейтинг: 0 / 0
05.03.2013, 13:32
    #38174558
NIIIK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
Glory,

План выполнения - это путь достижения постоянного результата.
Завтра план может поменятся по другой причине (статистика, данные, новый индекс для другого запроса изначально).

Оператор order by - не должен влиять на количество выводимых строк (не одним датастом, а обрабатываемых, как и в курсоре).

Разарабочик не должен думать о том что "если я измению порядок у меня изменится количество".

Оператор TOP ... НЕ ДОЛЖЕН возвращать больше строк чем БЕЗ этого оператора.
...
Рейтинг: 0 / 0
05.03.2013, 13:37
    #38174563
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKОператор order by - не должен влиять на количество выводимых строк (не одним датастом, а обрабатываемых, как и в курсоре).

Оператор TOP ... НЕ ДОЛЖЕН возвращать больше строк чем БЕЗ этого оператора.
Да причем тут количество записей ?

Вы меняете текст запроса. И оптимизатор вправе поменять план выполнения
Конкретно в данном случае меняется положение в плане шагов сортировки и вычисления выражений.
Вы хоть какой то план выполнения смотрели ?

NIIIKПлан выполнения - это путь достижения постоянного результата.
Для постоянного результата нужно использовать документированные методы.
...
Рейтинг: 0 / 0
05.03.2013, 13:38
    #38174564
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TOP + ORDER BY
NIIIKGlory,

План выполнения - это путь достижения постоянного результата.
Завтра план может поменятся по другой причине (статистика, данные, новый индекс для другого запроса изначально).

Оператор order by - не должен влиять на количество выводимых строк (не одним датастом, а обрабатываемых, как и в курсоре).

Разарабочик не должен думать о том что "если я измению порядок у меня изменится количество".

Оператор TOP ... НЕ ДОЛЖЕН возвращать больше строк чем БЕЗ этого оператора.Если всё это относится к обсуждаемой конструкции конкатенации строк,
то никто никому ничего не должен!
Говоря Вашими словами, "разарабочик не должен" применять эту недокументированную конструкцию
ввиду её нестабильной непредсказуемой работы.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / TOP + ORDER BY / 25 сообщений из 26, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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