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

Откуда: г. Екатеринбург
Сообщений: 667
Добрый день

Смотрю новые возможности MSSQL2016... появилась удобная функция STRING_SPLIT, которая переводит строковое значение в табличный вариант...

собственно вопрос, а есть что-то "обратное" т.е. функция, которая табличный вариант переведёт в строку с нужным разделителем?
15 авг 19, 10:38    [21949854]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Sergey Syrovatchenko
Member

Откуда: Харьков
Сообщений: 110
Нет. Самое лучшее что есть это FOR XML PATH
15 авг 19, 10:42    [21949864]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
4d_monster
Member

Откуда: Москва
Сообщений: 1570
Возможно подойдёт: STRING_AGG
15 авг 19, 11:01    [21949879]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
1C Developer
Member

Откуда:
Сообщений: 53
Что-то вроде этого?

SELECT I.table_name, LEFT(T.column_names , LEN(T.column_names )-1) AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;
15 авг 19, 11:02    [21949881]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
uaggster
Member

Откуда:
Сообщений: 731
4d_monster
Возможно подойдёт: STRING_AGG

Это с 2017+
15 авг 19, 11:04    [21949885]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 667
4d_monster
Возможно подойдёт: STRING_AGG


Да... то что надо)) но вот только не под mssql2016
15 авг 19, 11:09    [21949891]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 667
1C Developer
Что-то вроде этого?

SELECT I.table_name, LEFT(T.column_names , LEN(T.column_names )-1) AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;


Получается по старинке)) минус в постоянном использовании что-то типа "LEFT(T.column_names , LEN(T.column_names )-1)" ((
15 авг 19, 11:12    [21949893]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
invm
Member

Откуда: Москва
Сообщений: 8848
Игорь_UUS
минус в постоянном использовании что-то типа "LEFT(T.column_names , LEN(T.column_names )-1)" ((
SELECT I.table_name, T.column_names AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT case when row_number() over (order by 1/0) = 1 then '' else ', ' end + column_name
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;
15 авг 19, 11:44    [21949936]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
iap
Member

Откуда: Москва
Сообщений: 46899
invm
SELECT I.table_name, T.column_names AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT case when row_number() over (order by 1/0) = 1 then '' else ', ' end + column_name
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;
SELECT I.table_name, STUFF(T.column_names,1,2,'') AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT ', ' + column_name
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;
15 авг 19, 12:38    [21949997]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
iap
Member

Откуда: Москва
Сообщений: 46899
Более правильно, однако, так:
SELECT I.table_name, STUFF(T.column_names,1,2,'') AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT ', ' + QUOTENAME(column_name)
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;
15 авг 19, 12:41    [21950001]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Валдай
Member

Откуда:
Сообщений: 113
еще вариант для строк, в которых есть спецсимволы

if object_id('dbo.badcolumns','U') is not null drop table dbo.[badcolumns]
go
create table dbo.[badcolumns] (
  id int,
  [тут&что-то>странное] varchar(max)
)
go
SELECT I.table_name, T.column_names AS column_names
FROM information_schema.tables AS I
CROSS APPLY
( SELECT 
    STUFF( 
    ( SELECT [text()] = cast( ',' + column_name as varchar(max))
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH(''), TYPE ).value('.','varchar(max)'),1,1,'')
) T (column_names)
WHERE i.table_name = 'badcolumns'

--GROUP BY I.table_name, T.column_names;

SELECT I.table_name, LEFT(T.column_names , LEN(T.column_names )-1) AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
WHERE i.table_name = 'badcolumns'
GROUP BY I.table_name, T.column_names;
15 авг 19, 13:34    [21950064]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Александр Бердышев
Member

Откуда: Санкт-Петербург
Сообщений: 299
1C Developer
Что-то вроде этого?

SELECT I.table_name, LEFT(T.column_names , LEN(T.column_names )-1) AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;


Прикольно: первый раз с подобной проблемой столкнулся 7 лет назад - а подход до сих пор прежний...
Хорошо что хоть с 2017 версии сделали по-человечески.

Главное не делайте это отдельной функцией с курсором/циклом.
При запуске такой функции на таблице производительность упадёт примерно на 2 порядка.
15 авг 19, 13:47    [21950081]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6960
Игорь_UUS,

поищите CLR функции от Adam Machanic, работают быстрее SQL новодела.
15 авг 19, 15:33    [21950225]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3163
Александр Бердышев
1C Developer
Что-то вроде этого?

SELECT I.table_name, LEFT(T.column_names , LEN(T.column_names )-1) AS column_names
FROM information_schema.columns AS I
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE I.table_name = intern.table_name
    FOR XML PATH('')
) T (column_names)
GROUP BY I.table_name, T.column_names;


Прикольно: первый раз с подобной проблемой столкнулся 7 лет назад - а подход до сих пор прежний...
Хорошо что хоть с 2017 версии сделали по-человечески.

Главное не делайте это отдельной функцией с курсором/циклом.
При запуске такой функции на таблице производительность упадёт примерно на 2 порядка.


т.е. производительность упадёт в 20 раз?
16 авг 19, 10:34    [21950778]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
iap
Member

Откуда: Москва
Сообщений: 46899
Ролг Хупин
Александр Бердышев
пропущено...


Прикольно: первый раз с подобной проблемой столкнулся 7 лет назад - а подход до сих пор прежний...
Хорошо что хоть с 2017 версии сделали по-человечески.

Главное не делайте это отдельной функцией с курсором/циклом.
При запуске такой функции на таблице производительность упадёт примерно на 2 порядка.


т.е. производительность упадёт в 20 раз?
Два порядка - это в сто раз! :))
16 авг 19, 11:46    [21950872]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
лолл
Member

Откуда:
Сообщений: 450
Увы, Microsoft не смогли удачно реализовать STRING_AGG и STRING_SPLIT...
1. Оба не поддерживают в качестве разделителя строку (только один символ!).
2. Нет оконной STRING_AGG.
3. STRING_AGG не поддерживает DISTINCT и ее результат ограничен 8к символами.
16 авг 19, 17:03    [21951275]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
msLex
Member

Откуда:
Сообщений: 7001
лолл
Увы, Microsoft не смогли удачно реализовать STRING_AGG и STRING_SPLIT...
1. Оба не поддерживают в качестве разделителя строку (только один символ!).
2. Нет оконной STRING_AGG.
3. STRING_AGG не поддерживает DISTINCT и ее результат ограничен 8к символами.


из ваших "увы", полностью верный только 2-й


1.

select 
	string_agg(x.a, ' $separate string$ ')
from (
	values 
	  ('1')
	  , ('2')
) x (a)




3.

string-agg

Типы возвращаемых данных

Тип возвращаемого значения зависит от первого аргумента (expression). Если входной аргумент имеет строковый тип (NVARCHAR, VARCHAR), результат будет иметь тот же тип. В приведенной ниже таблице перечислены автоматические преобразования.
Тип входного выраженияРезультат
NVARCHAR(MAX)NVARCHAR(MAX)
VARCHAR(MAX)VARCHAR(MAX)
NVARCHAR(1...4000)NVARCHAR(4000)
VARCHAR(1...8000)VARCHAR(8000)
int, bigint, smallint, tinyint, numeric, float, real, bit, decimal, smallmoney, money, datetime, datetime2,NVARCHAR(4000)


16 авг 19, 17:43    [21951318]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
лолл
Member

Откуда:
Сообщений: 450
msLex,

select 
	string_agg(distinct x.a, ' $separate string$ ')
from (
	values 
	  ('1')
	  , ('2')
) x (a)


SELECT *
FROM STRING_SPLIT('1 $separate string$ 2', ' $separate string$ ')
21 авг 19, 15:58    [21954557]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
msLex
Member

Откуда:
Сообщений: 7001
лолл
msLex,

select 
	string_agg(distinct x.a, ' $separate string$ ')
from (
	values 
	  ('1')
	  , ('2')
) x (a)


SELECT *
FROM STRING_SPLIT('1 $separate string$ 2', ' $separate string$ ')



Читаем ваше утверждение

лолл
1. Оба не поддерживают в качестве разделителя строку (только один символ!).


Читаем мой комментарий

автор
полностью верный только 2-й


думаем
21 авг 19, 16:32    [21954606]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
лолл
Member

Откуда:
Сообщений: 450
msLex,

Это имеет значение, если придираться к точности формулировок. Я смотрю на вопрос иначе: есть то, что мне не нравится в реализации этих функций, я это озвучил (спасибо за устранение неточностей, которые были допущены при ответе на скорую руку).
21 авг 19, 18:45    [21954760]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
msLex
Member

Откуда:
Сообщений: 7001
лолл
msLex,

Это имеет значение, если придираться к точности формулировок. Я смотрю на вопрос иначе: есть то, что мне не нравится в реализации этих функций, я это озвучил (спасибо за устранение неточностей, которые были допущены при ответе на скорую руку).


Ровно половина описанных вами неудобств отсутвует. И чтобы узнать это, достаточно открыть справку. Это не неточности, это просто незнание. Как вы можете оценивать удобство этих функции, если не разобрались даже с требуемым вам функционалом?
21 авг 19, 20:23    [21954817]     Ответить | Цитировать Сообщить модератору
 Re: Существует ли обратная функция STRING_SPLIT  [new]
лолл
Member

Откуда:
Сообщений: 450
msLex,

Так оставьте ту половину неудобств, что присутствует, в чем проблема? Их достаточно, чтобы в некоторых случаях использовать альтернативные пути решения.
22 авг 19, 10:07    [21955117]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить