Как объединить строки в SQL?
Можно повелосипедить ))). Могу лишь предложить напрвление для поиска решения.
Зная сколько максимально может быть новых столбцов можно сначала сконкатенировать все в один (STRING_AGG).
А затем вот так — https://www.mssqltips.com/sqlservertip/6321/split-.
при этом для каких-то позиций часть столбцов будет пустая, а для каких-то они все будут заполнены.

DD-var, один столбец или несколько? сколько? записей с одинаковым detal можно быть бесконечно много. (ну так то).
И получается, что в вашем примере не хватает столбца mono4 со значением — ступицы.
Решения вопроса 1
alexalexes @alexalexes
Лучше, конечно, вертикальную выборку перерабатывать в горизонтальную не в SQL, а в той процедурной прослойке, которая вызывает запрос.
На SQL можно такое провернуть, но будет не универсально (фиксированное число столбцов в итоговой выборке).
with main_tb (id, detal, mono, row_num) as (select id, detal, mono row_number() over (partition by detal order by id) as row_num from tb) select t.id, t.detal, t.name, (select t1.mono from main_tb as t1 where t1.detal = t.detal and t1.row_num = 1) mono, (select t1.mono from main_tb as t1 where t1.detal = t.detal and t1.row_num = 2) mono2, (select t1.mono from main_tb as t1 where t1.detal = t.detal and t1.row_num = 3) mono3 from tb as t
Ответ написан более года назад
Комментировать
Нравится Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- C#
- +2 ещё
Возможно ли получить tcp-сокет в C#-приложении? Или как узнать IP?
- 1 подписчик
- 17 нояб.
- 84 просмотра
Как объединить строки в sql?
Я выбираю из таблицы строки, у которых одинаковый Id:
Select * From table Where > У меня выводится две строки, которые я хочу преобразовать в одну. Как мне это сделать?
- Вопрос задан более трёх лет назад
- 1281 просмотр
3 комментария
Простой 3 комментария

У каждой СУБД свои способы, Укажите в тегах, которая вас интересует.
alexalexes @alexalexes
Тут еще могут быть вопросы к архитектуре таблицы.
Если id предполагает роль первичного ключа, то почему он таковым не является, почему есть необходимость извлекать дубликаты?

Сергей П @trapwalker
alexalexes, ну видимо сначала были данные а теперь их хочется дедуплицировать.
Решения вопроса 0
Ответы на вопрос 1
Эм. Group by?
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- SQL
- +1 ещё
Массив структур в Hive. Как проверить вхождение в массив структуры по маске?
- 1 подписчик
- вчера
- 72 просмотра
Конкатенация строк в T-SQL

Как уже говорилось, в стандарте SQL определены только два типа функций упорядоченного набора: функции гипотетического набора (RANK, DENSE_RANK, PERCENT_RANK и CUME_DIST) и функции обратного распределения (PERCENTILE_DISC и PERCENTILE_CONT). Как я уже демонстрировал на примере функций сдвига, нет причины, по которой эта концепция не работала бы и для других функций. Основная идея состоит в том, что если это агрегирующая функция, результат вычислении которой зависит от порядка следования элементов, это возможный кандидат на функцию упорядоченного набора.
Возьмем такой классический пример как конкатенация строки. К сожалению, на настоящий момент не существует встроенной агрегирующей функции конкатенации строки, которая бы соединяла группу строк. Но допустим, что такая функция существует. Конечно же, у вас может возникнуть необходимость в конкатенации группы строк в некотором порядке, поэтому имеет смысл реализовать такую функцию как функцию упорядоченного набора с предложением WITHIN GROUP, которое позволяет задать параметры упорядочения.
В Oracle, например, такая функция реализована (называется LISTAGG) как функция упорядоченного набора. Итак, чтобы обратиться к таблице с именем Sales.Orders и вернуть для каждого клиента строку со значениями orderid конкатенированными в порядке orderid, используйте следующий код:
-- Для Oracle SELECT custid, LISTAGG(orderid, ',') WITHIN GROUP(ORDER BY orderid) AS custorders FROM Sales.Orders GROUP BY custid;

В SQL Server разработчики прибегают к самым разным альтернативным решениям, чтобы получить конкатенацию строк в определенном порядке. Один из наиболее эффективных приемов основывается на обработке XML с использованием параметра FOR XML в режиме PATH, примерно так:
SELECT custid, COALESCE( STUFF( (SELECT ',' + CAST(orderid AS VARCHAR(10)) AS [text()] FROM Sales.Orders AS O WHERE O.custid = C.custid ORDER BY orderid FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, ''), '') AS custorders FROM Sales.Customers AS C;
Расположенный на самом нижнем уровне вложения связанный вложенный запрос отфильтровывает только значения orderid из таблицы Orders (псевдоним O), которые связаны с текущим клиентом из таблицы Customers (псевдоним C). Используя предложение FOR XML PATH, можно объединить все значения одну строку XML. Использование пустой строки как входного значения в режиме PATH означает, что инкапсулирующие элементы не нужны, поэтому мы получаем конкатенацию значений без всяких тегов. Так как вложенный запрос содержит ORDER BY orderid, значения orderid в строке будут упорядочены. Заметьте, что упорядочивать можно по любому признаку — не обязательно по значениям, которые конкатенируются. Приведенный код также добавляет запятую в качестве разделителя перед каждым значением orderid, а затем функция STUFF удаляет первую запятую. И наконец, функция COALESCE преобразует результат NULL в пустую строку. Итак, мы видим, что существует возможность получить в SQL Server конкатенацию строк в определенном порядке, но выглядит это не очень изящно.
Итак, функции упорядоченного набора, которые мы рассмотрели ранее, это агрегирующие функции, результат вычисления которых зависит от упорядочения. В стандарте определено несколько специализированных функций, но принцип является общим и может применяться ко всем видам вычислений агрегатов. Я привел несколько примеров, выходящих за пределы поддерживаемого стандарта, — это функции смещения и конкатенация строк. SQL Server 2012 не поддерживает функции упорядоченного набора данных, но я привел альтернативные методы для получения аналогичной функциональности. Я очень надеюсь, что в будущем мы увидим в SQL Server поддержку таких функций — возможно, они будут реализовывать стандартное предложение WITHIN GROUP и будут доступны через пользовательские CLR-функции агрегирования, учитывающие упорядочение.
Как сложить строки в sql
В этом разделе описаны функции и операторы для работы с текстовыми строками. Под строками в данном контексте подразумеваются значения типов character , character varying и text . Если не отмечено обратное, все нижеперечисленные функции работают со всеми этими типами, хотя с типом character следует учитывать возможные эффекты автоматического дополнения строк пробелами. Некоторые из этих функций также поддерживают битовые строки.
В SQL определены несколько строковых функций, в которых аргументы разделяются не запятыми, а ключевыми словами. Они перечислены в Таблице 9.6. Postgres Pro также предоставляет варианты этих функций с синтаксисом, обычным для функций (см. Таблицу 9.7).
Примечание
До версии 8.3 в PostgreSQL эти функции также прозрачно принимали значения некоторых не строковых типов, неявно приводя эти значения к типу text . Сейчас такие приведения исключены, так как они часто приводили к неожиданным результатам. Однако оператор конкатенации строк ( || ) по-прежнему принимает не только строковые данные, если хотя бы один аргумент имеет строковый тип, как показано в Таблице 9.6. Во всех остальных случаях для повторения предыдущего поведения потребуется добавить явное преобразование в text .
Таблица 9.6. Строковые функции и операторы языка SQL
| Функция | Тип результата | Описание | Пример | Результат |
|---|---|---|---|---|
| string || string | text | Конкатенация строк | ‘Post’ || ‘greSQL’ | PostgreSQL |
| string || не string или не string || string | text | Конкатенация строк с одним не строковым операндом | ‘Value: ‘ || 42 | Value: 42 |
| bit_length( string ) | int | Число бит в строке | bit_length(‘jose’) | 32 |
| char_length( string ) или character_length( string ) | int | Число символов в строке | char_length(‘jose’) | 4 |
| lower( string ) | text | Переводит символы строки в нижний регистр | lower(‘TOM’) | tom |
| octet_length( string ) | int | Число байт в строке | octet_length(‘jose’) | 4 |
| overlay( string placing string from int [ for int ]) | text | Заменяет подстроку | overlay(‘Txxxxas’ placing ‘hom’ from 2 for 4) | Thomas |
| position( substring in string ) | int | Положение указанной подстроки | position(‘om’ in ‘Thomas’) | 3 |
| substring( string [ from int ] [ for int ]) | text | Извлекает подстроку | substring(‘Thomas’ from 2 for 3) | hom |
| substring( string from шаблон ) | text | Извлекает подстроку, соответствующую регулярному выражению в стиле POSIX. Подробно шаблоны описаны в Разделе 9.7. | substring(‘Thomas’ from ‘. $’) | mas |
| substring( string from шаблон for спецсимвол ) | text | Извлекает подстроку, соответствующую регулярному выражению в стиле SQL . Подробно шаблоны описаны в Разделе 9.7. | substring(‘Thomas’ from ‘%#»o_a#»_’ for ‘#’) | oma |
| trim([ leading | trailing | both ] [ characters ] from string ) | text | Удаляет наибольшую подстроку, содержащую только символы characters (по умолчанию пробелы), с начала ( leading ), с конца ( trailing ) или с обеих сторон ( both , (по умолчанию)) строки string | trim(both ‘xyz’ from ‘yxTomxx’) | Tom |
| trim([ leading | trailing | both ] [ from ] string [ , characters ] ) | text | Нестандартный синтаксис trim() | trim(both from ‘yxTomxx’, ‘xyz’) | Tom |
| upper( string ) | text | Переводит символы строки в верхний регистр | upper(‘tom’) | TOM |
Кроме этого, в PostgreSQL есть и другие функции для работы со строками, перечисленные в Таблице 9.7. Некоторые из них используются в качестве внутренней реализации стандартных строковых функций SQL , приведённых в Таблице 9.6.
Таблица 9.7. Другие строковые функции
| Функция | Тип результата | Описание | Пример | Результат |
|---|---|---|---|---|
| ascii( string ) | int | Возвращает ASCII -код первого символа аргумента. Для UTF8 возвращает код символа в Unicode. Для других многобайтных кодировок аргумент должен быть ASCII -символом. | ascii(‘x’) | 120 |
| btrim( string text [ , characters text ]) | text | Удаляет наибольшую подстроку, состоящую только из символов characters (по умолчанию пробелов), с начала и с конца строки string | btrim(‘xyxtrimyyx’, ‘xyz’) | trim |
| chr( int ) | text | Возвращает символ с данным кодом. Для UTF8 аргумент воспринимается как код символа Unicode, а для других кодировок он должен указывать на ASCII -символ. Код 0 (NULL) не допускается, так как байты с нулевым кодом в текстовых строках сохранить нельзя. | chr(65) | A |
| concat( str «any» [, str «any» [, . ] ]) | text | Соединяет текстовые представления всех аргументов, игнорируя NULL. | concat(‘abcde’, 2, NULL, 22) | abcde222 |
| concat_ws( sep text , str «any» [, str «any» [, . ] ]) | text | Соединяет все аргументы, кроме первого, через разделитель, игнорируя аргументы NULL. Разделитель указывается в первом аргументе. | concat_ws(‘,’, ‘abcde’, 2, NULL, 22) | abcde,2,22 |
| convert( string bytea , src_encoding name , dest_encoding name ) | bytea | Преобразует строку string из кодировки src_encoding в dest_encoding . Переданная строка должна быть допустимой для исходной кодировки. Преобразования могут быть определены с помощью CREATE CONVERSION . Все встроенные преобразования перечислены в Таблице 9.8. | convert(‘text_in_utf8’, ‘UTF8’, ‘LATIN1’) | строка text_in_utf8 , представленная в кодировке Latin-1 (ISO 8859-1) |
| convert_from( string bytea , src_encoding name ) | text | Преобразует строку string из кодировки src_encoding в кодировку базы данных. Переданная строка должна быть допустимой для исходной кодировки. | convert_from(‘text_in_utf8’, ‘UTF8’) | строка text_in_utf8 , представленная в кодировке текущей базы данных |
| convert_to( string text , dest_encoding name ) | bytea | Преобразует строку в кодировку dest_encoding . | convert_to(‘некоторый текст’, ‘UTF8’) | некоторый текст , представленный в кодировке UTF8 |
| decode( string text , format text ) | bytea | Получает двоичные данные из текстового представления в string . Значения параметра format те же, что и для функции encode . | decode(‘MTIzAAE=’, ‘base64’) | \x3132330001 |
| encode( data bytea , format text ) | text | Переводит двоичные данные в текстовое представление в одном из форматов: base64 , hex , escape . Формат escape преобразует нулевые байты и байты с 1 в старшем бите в восьмеричные последовательности \nnn и дублирует обратную косую черту. | encode(‘123\000\001’, ‘base64’) | MTIzAAE= |
| format ( formatstr text [, formatarg «any» [, . ] ]) | text | Форматирует аргумент в соответствии со строкой формата. Эта функция работает подобно sprintf в языке C. См. Подраздел 9.4.1. | format(‘Hello %s, %1$s’, ‘World’) | Hello World, World |
| initcap( string ) | text | Переводит первую букву каждого слова в строке в верхний регистр, а остальные — в нижний. Словами считаются последовательности алфавитно-цифровых символов, разделённые любыми другими символами. | initcap(‘hi THOMAS’) | Hi Thomas |
| left( str text , n int ) | text | Возвращает первые n символов в строке. Когда n меньше нуля, возвращаются все символы слева, кроме последних | n |. | left(‘abcde’, 2) | ab |
| length( string ) | int | Число символов в строке string | length(‘jose’) | 4 |
| length( string bytea , encoding name ) | int | Число символов, которые содержит строка string в заданной кодировке encoding . Переданная строка должна быть допустимой в этой кодировке. | length(‘jose’, ‘UTF8’) | 4 |
| lpad( string text , length int [ , fill text ]) | text | Дополняет строку string слева до длины length символами fill (по умолчанию пробелами). Если длина строки уже больше заданной, она обрезается справа. | lpad(‘hi’, 5, ‘xy’) | xyxhi |
| ltrim( string text [ , characters text ]) | text | Удаляет наибольшую подстроку, содержащую только символы characters (по умолчанию пробелы), с начала строки string | ltrim(‘zzzytest’, ‘xyz’) | test |
| md5( string ) | text | Вычисляет MD5-хеш строки string и возвращает результат в 16-ричном виде | md5(‘abc’) | 900150983cd24fb0 d6963f7d28e17f72 |
| pg_client_encoding() | name | Возвращает имя текущей клиентской кодировки | pg_client_encoding() | SQL_ASCII |
| quote_ident( string text ) | text | Переданная строка оформляется для использования в качестве идентификатора в SQL -операторе. При необходимости идентификатор заключается в кавычки (например, если он содержит символы, недопустимые в открытом виде, или буквы в разном регистре). Если переданная строка содержит кавычки, они дублируются. См. также Пример 40.1. | quote_ident(‘Foo bar’) | «Foo bar» |
| quote_literal( string text ) | text | Переданная строка оформляется для использования в качестве текстовой строки в SQL -операторе. Включённые символы апостроф и обратная косая черта при этом дублируются. Заметьте, что quote_literal возвращает NULL, когда на вход ей передаётся строка NULL; если же нужно получить представление и такого аргумента, лучше использовать quote_nullable . См. также Пример 40.1. | quote_literal(E’O\’Reilly’) | ‘O»Reilly’ |
| quote_literal( value anyelement ) | text | Переводит данное значение в текстовый вид и заключает в апострофы как текстовую строку. Символы апостроф и обратная косая черта при этом дублируются. | quote_literal(42.5) | ‘42.5’ |
| quote_nullable( string text ) | text | Переданная строка оформляется для использования в качестве текстовой строки в SQL -операторе; при этом для аргумента NULL возвращается строка NULL . Символы апостроф и обратная косая черта дублируются должным образом. См. также Пример 40.1. | quote_nullable(NULL) | NULL |
| quote_nullable( value anyelement ) | text | Переводит данное значение в текстовый вид и заключает в апострофы как текстовую строку, при этом для аргумента NULL возвращается строка NULL . Символы апостроф и обратная косая черта дублируются должным образом. | quote_nullable(42.5) | ‘42.5’ |
| regexp_matches( string text , pattern text [, flags text ]) | setof text[] | Возвращает все подходящие подстроки, полученные в результате применения регулярного выражения в стиле POSIX к string . Подробности описаны в Подразделе 9.7.3. | regexp_matches(‘foobarbequebaz’, ‘(bar)(beque)’) | |
| regexp_replace( string text , pattern text , replacement text [, flags text ]) | text | Заменяет подстроки, соответствующие заданному регулярному выражению в стиле POSIX. Подробности описаны в Подразделе 9.7.3. | regexp_replace(‘Thomas’, ‘.[mN]a.’, ‘M’) | ThM |
| regexp_split_to_array( string text , pattern text [, flags text ]) | text[] | Разделяет содержимое string на элементы, используя в качестве разделителя регулярное выражение POSIX. Подробности описаны в Подразделе 9.7.3. | regexp_split_to_array(‘hello world’, ‘\s+’) | |
| regexp_split_to_table( string text , pattern text [, flags text ]) | setof text | Разделяет содержимое string на элементы, используя в качестве разделителя регулярное выражение POSIX. Подробности описаны в Подразделе 9.7.3. | regexp_split_to_table(‘hello world’, ‘\s+’) | hello |
Функции concat , concat_ws и format принимают переменное число аргументов, так что им для объединения или форматирования можно передавать значения в виде массива, помеченного ключевым словом VARIADIC (см. Подраздел 35.4.5). Элементы такого массива обрабатываются, как если бы они были обычными аргументами функции. Если вместо массива в соответствующем аргументе передаётся NULL, функции concat и concat_ws возвращают NULL, а format воспринимает NULL как массив нулевого размера.
См. также агрегатную функцию string_agg в Разделе 9.20.
Таблица 9.8. Встроенные преобразования
[a] Имена преобразований следуют стандартной схеме именования. К официальному названию исходной кодировки, в котором все не алфавитно-цифровые символы заменяются подчёркиваниями, добавляется _to_ , а за ним аналогично подготовленное имя целевой кодировки. Таким образом, имена кодировок могут не совпадать буквально с общепринятыми названиями.
9.4.1. format
Функция format выдаёт текст, отформатированный в соответствии со строкой формата, подобно функции sprintf в C.
format(formatstrtext[,formatarg"any"[, . ] ])
formatstr — строка, определяющая, как будет форматироваться результат. Обычный текст в строке формата непосредственно копируется в результат, за исключением спецификаторов формата. Спецификаторы формата представляют собой местозаполнители, определяющие, как должны форматироваться и выводиться в результате аргументы функции. Каждый аргумент formatarg преобразуется в текст по правилам выводам своего типа данных, а затем форматируется и вставляется в результирующую строку согласно спецификаторам формата.
Спецификаторы формата предваряются символом % и имеют форму
%[позиция][флаги][ширина]тип
позиция (необязателен)
Строка вида n $ , где n — индекс выводимого аргумента. Индекс, равный 1, выбирает первый аргумент после formatstr . Если позиция опускается, по умолчанию используется следующий аргумент по порядку. флаги (необязателен)
Дополнительные параметры, управляющие форматированием данного спецификатора. В настоящее время поддерживается только знак минус ( — ), который выравнивает результата спецификатора по левому краю. Он работает, только если также определена ширина . ширина (необязателен)
Задаёт минимальное число символов, которое будет занимать результат данного спецификатора. Выводимое значение выравнивается по правой или левой стороне (в зависимости от флага — ) с дополнением необходимым числом пробелов. Если ширина слишком мала, она просто игнорируется, т. е. результат не усекается. Ширину можно обозначить положительным целым, звёздочкой ( * ), тогда ширина будет получена из следующего аргумента функции, или строкой вида * n $ , тогда ширина будет задаваться в n -ом аргументе функции.
Если ширина передаётся в аргументе функции, этот аргумент выбирается до аргумента, используемого для спецификатора. Если аргумент ширины отрицательный, результат выравнивается по левой стороне (как если бы был указан флаг — ) в рамках поля длины abs ( ширина ). тип (обязателен)
Тип спецификатора определяет преобразование соответствующего выводимого значения. Поддерживаются следующие типы:
s форматирует значение аргумента как простую строку. Значение NULL представляется пустой строкой.
I обрабатывает значение аргумента как SQL-идентификатор, при необходимости заключая его в кавычки. Значение NULL для такого преобразования считается ошибочным (так же, как и для quote_ident ).
В дополнение к спецификаторам, описанным выше, можно использовать спецпоследовательность %% , которая просто выведет символ % .
Несколько примеров простых преобразований формата:
SELECT format('Hello %s', 'World'); Результат: Hello World SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three'); Результат: Testing one, two, three, % SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); Результат: INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); Результат: INSERT INTO locations VALUES('C:\Program Files')
Следующие примеры иллюстрируют использование поля ширина и флага — :
SELECT format('|%10s|', 'foo'); Результат: | foo| SELECT format('|%-10s|', 'foo'); Результат: |foo | SELECT format('|%*s|', 10, 'foo'); Результат: | foo| SELECT format('|%*s|', -10, 'foo'); Результат: |foo | SELECT format('|%-*s|', 10, 'foo'); Результат: |foo | SELECT format('|%-*s|', -10, 'foo'); Результат: |foo |
Эти примеры показывают применение полей позиция :
SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); Результат: Testing three, two, one SELECT format('|%*2$s|', 'foo', 10, 'bar'); Результат: | bar| SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); Результат: | foo|
В отличие от стандартной функции C sprintf , функция format в Postgres Pro позволяет комбинировать в одной строке спецификаторы с полями позиция и без них. Спецификатор формата без поля позиция всегда использует следующий аргумент после последнего выбранного. Кроме того, функция format не требует, чтобы в строке формата использовались все аргументы функции. Пример этого поведения:
SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Результат: Testing three, two, three
Спецификаторы формата %I и %L особенно полезны для безопасного составления динамических операторов SQL. См. Пример 40.1.
| Пред. | Наверх | След. |
| 9.3. Математические функции и операторы | Начало | 9.5. Функции и операторы двоичных строк |
