Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Почему запрос на агрегацию строк с for xml так странно работает? / 9 сообщений из 9, страница 1 из 1
05.02.2018, 08:29
    #39596529
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему запрос на агрегацию строк с for xml так странно работает?
Собственно, текст запроса вот:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Declare @t table (id int, id2 int, t varchar(255))

insert into @t 
Values
(1, 1, 't1'),
(1, 1, 't2'),
(1, 1, 't3'),
(2, 2, 't4'),
(3, 2, 't5'),
(4, 1, 't6')

Select Distinct a.id, c.t from @t a
	Cross apply
		(select '/' + b.t as [data()]
		from @t b
			where a.id = b.id2
		--for xml path('')
		) c(t)  


С закомментированнным for xml path('') он отрабатывает ожидаемо:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
id	t
1	/t1
1	/t2
1	/t3
1	/t6
2	/t4
2	/t5
А вот с раскомментированным - неожиданно!
Код: plaintext
1.
2.
3.
4.
5.
id	t
1	/t1 /t2 /t3 /t6
2	/t4 /t5
3	NULL
4	NULL

Почему???
Воспроизводится и на 2008R2, и на 2016SP1.
...
Рейтинг: 0 / 0
05.02.2018, 08:32
    #39596530
Почему запрос на агрегацию строк с for xml так странно работает?
uaggster,

что именно тебя удивляет?
...
Рейтинг: 0 / 0
05.02.2018, 08:44
    #39596534
Почему запрос на агрегацию строк с for xml так странно работает?
uaggster,

если что, кури в сторону агрегатных запросов без фразы GROUP BY....
сравни результат вывода:

Код: sql
1.
2.
select max(id2) from @t where 1 = 2
select max(id2) from @t where 1 = 2 group by id


в первом случае ты получаешь результирующий набор в одну строку с ПУСТЫМ ЗНАЧЕНИЕМ.
во втором - ПУСТОЕ МНОЖЕСТВО, не содержание ни одной строки.
Чувствуешь разницу?
...
Рейтинг: 0 / 0
05.02.2018, 09:09
    #39596541
Почему запрос на агрегацию строк с for xml так странно работает?
uaggster,

ну, если вдруг, ты не понял аналогии, то for xml path('') - это, как бы, "аналог" агрегатного подзапроса без кляузы GROPU BY. То есть, он всегда вернет "одну строку" на выходе, вне зависимости от ложности или истинности условий соединения со внешней таблицей...
Другое дело, что эта "одна строка" будет либо содержать результат конкатенации всех строк, удовлетворяющих условию WHERE, либо "пустное значение", если условия WHERE окажется "ложным"
...
Рейтинг: 0 / 0
05.02.2018, 09:12
    #39596544
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему запрос на агрегацию строк с for xml так странно работает?
Добрый Э - Эхuaggster,

что именно тебя удивляет?
Меня удивляет, что (вроде бы) если cross apply не вернул ни одной строки, значит и строка, с которой происходит соединение, и результат функции (в данном случае - подчиненный селект) - в выборку попасть не должны.
Вроде бы.
...
Рейтинг: 0 / 0
05.02.2018, 09:14
    #39596546
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему запрос на агрегацию строк с for xml так странно работает?
Добрый Э - Эхuaggster,

ну, если вдруг, ты не понял аналогии, то for xml path('') - это, как бы, "аналог" агрегатного подзапроса без кляузы GROPU BY. То есть, он всегда вернет "одну строку" на выходе, вне зависимости от ложности или истинности условий соединения со внешней таблицей...
Другое дело, что эта "одна строка" будет либо содержать результат конкатенации всех строк, удовлетворяющих условию WHERE, либо "пустное значение", если условия WHERE окажется "ложным"
А почему это так???
Чем диктуется такое поведение?
...
Рейтинг: 0 / 0
05.02.2018, 09:16
    #39596548
Почему запрос на агрегацию строк с for xml так странно работает?
uaggster,

ещё раз говорю - проделай эксперимент с агрегатным подзапросом без GROUP BY. Результат будет аналогичный, потому что агрегатный запрос (читай с for xml) без group by - всегда возвращает ровно одну строку, вне зависимости от числа строк, попавших в обработку...
Касательно apply - он при cross нотации возвращает в итоговый датасет строки, для которых подзапрос оказался "непустым множеством".
так вот, твой for xml делает результирующий датасет подзапроса - "непустым"... потому строки из основной таблицы и выталкиваются в итоговый результат...
...
Рейтинг: 0 / 0
05.02.2018, 09:17
    #39596549
Почему запрос на агрегацию строк с for xml так странно работает?
uaggsterА почему это так???
Чем диктуется такое поведение?документацией и стандартом ANSI-SQL
...
Рейтинг: 0 / 0
05.02.2018, 10:52
    #39596598
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему запрос на агрегацию строк с for xml так странно работает?
Добрый Э - Эхтак вот, твой for xml делает результирующий датасет подзапроса - "непустым"... потому строки из основной таблицы и выталкиваются в итоговый результат...
Выделенное курсивом - разумеется, понятно.
Непонятное - выделенное жирным.

Почему for xml - делает результат датасета - непустым?
Я понимаю, что это диктуется стандартом (если б это можно было списать на баг, это не воспроизводилось бы на разных версиях), не не понимаю, где это посмотреть!
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Почему запрос на агрегацию строк с for xml так странно работает? / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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