Конкатентные значения всех столбцов в sql
Как конкатрировать все значения столбцов из строк differenct, возвращаемых из SQL-запроса, в одно значение? Это пример:
возвращает запрос:
FOO
------
RES1
RES2
RES3
теперь я хочу получить результат, похожий на следующий:
FOOCONCAT
-----
RES1RES2RES3
Есть ли способ сделать это в sql?
Ответы
Ответ 1
В SQL Server
:
SELECT col1 AS [text()]
FROM foo
FOR XML PATH ('')
В MySQL
:
SELECT GROUP_CONCAT(col1 SEPARATOR '')
FROM foo
В PostgreSQL
:
SELECT array_to_string
(
ARRAY
(
SELECT col1
FROM foo
), ''
)
В Oracle
:
SELECT *
FROM (
SELECT col1, ROW_NUMBER() OVER(ORDER BY 1) AS rn
FROM foo
MODEL
DIMENSION BY
(rn)
MEASURES
(col1, col1 AS group_concat, 0 AS mark)
RULES UPDATE (
group_concat[rn > 1] = group_concat[CV() - 1] || col1[CV()],
mark[ANY] = PRESENTV(mark[CV() + 1], 0, 1)
)
)
WHERE mark = 1
Ответ 2
Quassnoi Oracle довольно впечатляет, но я нашел более простой с использованием SYS_CONNECT_BY_PATH(), а не магии MODEL.
SELECT REPLACE(MAX(SYS_CONNECT_BY_PATH(foo, '/')), '/', '') conc
FROM (
SELECT T_FOO.*, ROW_NUMBER() OVER (ORDER BY FOO) R FROM T_FOO
)
START WITH r=1
CONNECT BY PRIOR r = r-1;
Ответ 3
Предполагая, что это один столбец с несколькими значениями, этот подход работает для MS SQL Server (я не могу говорить для других систем).
declare @result varchar(max)
set @result = ''
select @result = @result + RES
from (query goes here)
Ответ 4
Способ mysql:
select group_concat(somecolumn separator '') from sometable
Ответ 5
Вот ответ, который вы ищете; У меня было ощущение, что решение лежит в операции CONNECT BY, я раньше не использовал псевдокоманду SYS_CONNECT_BY_PATH (которая отображает полный путь к node в дереве, разделяя имена node на "/" ). Предполагая, что ваш набор значений "foo" до этого представляет собой несколько строк в таблице, сгруппированных по столбцу "myKey", например:
myKey foo
-------- ----------
group 1 apple
group 1 orange
group 1 pear
group 2 ape
group 2 bear
group 2 kitten
вы можете обрабатывать данные так, как если бы это была схема дерева, и притворяться, что значения каждой группы представляют собой узлы, идущие вниз по ветки. В этом случае вы сделаете следующее:
SELECT myKey
, SUBSTR(MAX(REPLACE(SYS_CONNECT_BY_PATH(foo, '/')
,'/'
,' '
)
)
,2
) FooConcat
FROM ( SELECT MyKey
, Foo
, row_number() OVER (Partition by myKey order by myKey) NodeDepth
FROM MyTable
)
START WITH NodeDepth = 1
CONNECT BY PRIOR myKey = myKey
AND PRIOR NodeDepth = NodeDepth -1
GROUP BY myKey
;
Конечно, порядок конкатенированных значений будет случайным; если в вашей таблице был другой столбец ( "бар" ), который вы могли бы использовать в качестве поля упорядочения, которое было восходящим и смежным, вы могли бы обойтись без подзапроса (который существует только для того, чтобы поместить воображаемую глубину в дерево) и использовать таблицу напрямую, заменив NodeDepth на панель.
Ответ 6
Изменить: Начиная с версии 8.4.0 CUBRID предоставляет 90% совместимость с MySQL. Таким образом, он поддерживает GROUP_CONCAT, который имеет похожий синтаксис, как в MySQL:
CREATE TABLE t(i int);
INSERT INTO t VALUES (4),(2),(3),(6),(1),(5);
SELECT GROUP_CONCAT(i*2+1 ORDER BY 1 SEPARATOR '') FROM t;
group_concat(i*2+1 order by 1 separator '')
======================
'35791113'
Довольно мощный, не так ли? А ниже - альтернативное решение поддерживаемое изначально в CUBRID.
SELECT MAX(SYS_CONNECT_BY_PATH(s_name, '')) AS conc_s_name
FROM (
SELECT ROWNUM AS r, s_name FROM code
) AS res
START WITH r = 1
CONNECT BY PRIOR r = r - 1;
Так интересно, что этот способ объединения значений столбцов строк в CUBRID почти идентичен пути Oracle, предоставленному @devio. В CUBRID это выглядит немного легче, хотя.
Ответ 7
select cast(res1 as varchar)+cast(res2 as varchar)+cast(res3 as varchar) as fooconcat from foo
Если столбцы уже являются строками, вам не нужно делать актеры, вы можете просто сделать:
select res1 + res2 + res3 as fooconcat from foo
Для данных из нескольких строк используйте PIVOT.
Ответ 8
Конкатенация строк зависит от используемой вами базы данных (вы havnt указали, какая версия в вашем вопросе так здесь)...
В Oracle и DB2 вы можете использовать функцию CONCAT
... CONCAT(string, string)
SQL Server вы можете использовать оператор "+"... string1 + string2 + string3
В MySQL это CONCAT(string, string... n_string)
Наконец, в PostgreSQL это TEXTCAT(string, string)
...
... Я получил это из этой маленькой классной книги, которую я сижу на своем столе. Книга SQL Pocket Guide от O'Reilly... проверьте это!
:)
Ответ 9
Возможно, это не то, что вы ищете, но мне повезло в прошлом с такими конструкциями:
SELECT MAX(DECODE(fookey, 1, foo, NULL))
|| MAX(DECODE(fookey, 2, foo, NULL))
|| MAX(DECODE(fookey, 3, foo, NULL))
|| MAX(DECODE(fookey, 4, foo, NULL))
, groupingvalue
FROM mytable
GROUP BY groupingvalue;
Эта платформа независима, и она хорошо работает, когда у вас есть произвольное, но ограниченное количество значений для foo, и они основаны на другом ключевом значении. Например, если у вас есть таблица счетов-фактур, и вы хотите видеть все строки времени из счета-фактуры в одной строке, объединены и у вас есть верхний предел в 5 позиций, это будет выглядеть так:
SELECT MAX(DECODE(lineno, 1, foo, NULL))
|| ', '
|| MAX(DECODE(lineno, 2, foo, NULL))
|| ', '
|| MAX(DECODE(lineno, 3, foo, NULL))
|| ', '
|| MAX(DECODE(lineno, 4, foo, NULL))
|| ', '
|| MAX(DECODE(lineno, 5, foo, NULL))
, invoiceid
FROM lineitem
GROUP BY invoiceid;
Ответ 10
SQL Server 2008 R2:
declare @ColumnNameList VARCHAR(MAX)
SELECT @ColumnNameList = COALESCE(@ColumnNameList +',' ,'') + ColumnName
FROM
<<table name>>
select @ColumnNameList
Ответ 11
Выберите [[col1] + ',' + [col2] + ',' + [col3] + ',' + [col4]) в качестве [MyCol] из [Таблица]