SQL 2005 Слияние / объединение нескольких строк в один столбец. Объединение строк sql
sql-server - SQL Server: объединение нескольких строк в одну строку
Существует несколько методов.
Если вы хотите вернуть только консолидированное строковое значение, это хороший быстрый и легкий подход
DECLARE @combinedString VARCHAR(MAX) SELECT @combinedString = COALESCE(@combinedString + ', ', '') + stringvalue FROM jira.customfieldValue WHERE customfield = 12534 AND ISSUE = 19602 SELECT @combinedString as StringValueКоторый вернет вашу объединенную строку.
Вы также можете попробовать один из методов XML, например
SELECT DISTINCT Issue, Customfield, StringValues FROM Jira.customfieldvalue v1 CROSS APPLY ( SELECT StringValues + ',' FROM jira.customfieldvalue v2 WHERE v2.Customfield = v1.Customfield AND v2.Issue = v1.issue ORDER BY ID FOR XML PATH('') ) D ( StringValues ) WHERE customfield = 12534 AND ISSUE = 19602В MySql есть удобный способ для этого - GROUP_CONCAT. Эквивалент для SQL Server не существует, но вы можете написать свой собственный, используя SQLCLR. К счастью, someone уже сделал это за вас.
Затем ваш запрос превращается в это (что лучше всего подходит синтаксису btw):
SELECT CUSTOMFIELD, ISSUE, dbo.GROUP_CONCAT(STRINGVALUE) FROM Jira.customfieldvalue WHERE CUSTOMFIELD = 12534 AND ISSUE = 19602 GROUP BY CUSTOMFIELD, ISSUEНо учтите, что этот метод подходит для более чем 100 строк внутри группы . Кроме того, у вас будут серьезные проблемы с производительностью. Агрегаты SQLCLR должны сериализовать промежуточные результаты и быстро накапливаются до довольно большой работы. Имейте это в виду!
Интересно, что FOR XML не страдает от одной и той же проблемы, но вместо этого использует этот ужасающий синтаксис.
Я считаю, что для баз данных, поддерживающих функцию listagg , вы можете:
select id, issue, customfield, parentkey, listagg(stingvalue, ',') within group (order by id) from jira.customfieldvalue where customfield = 12534 and issue = 19602 group by id, issue, customfield, parentkeycode-examples.net
Объединение строк в SQL (Oracle)
Вот один из способов (при условии, что вы могли бы иметь перекрывающиеся строки, в которых диапазон начало текущей строки меньше или равно конечному диапазона предыдущего ряда):
with sample_data as (select 1 id, 10 lower_range, 20 upper_range, 'A' attribute from dual union all select 2 id, 20 lower_range, 30 upper_range, 'A' attribute from dual union all select 3 id, 40 lower_range, 50 upper_range, 'A' attribute from dual union all select 4 id, 15 lower_range, 35 upper_range, 'B' attribute from dual union all select 5 id, 45 lower_range, 55 upper_range, 'A' attribute from dual union all select 6 id, 16 lower_range, 34 upper_range, 'B' attribute from dual) select min(id) id, min(lower_range) lower_range, max(upper_range) upper_range, attribute from (select id, lower_range, upper_range, attribute, sum(diff) over (partition by attribute order by lower_range, upper_range) grp from (select id, lower_range, upper_range, attribute, case when lag(upper_range, 1, lower_range) over (partition by attribute order by lower_range, upper_range) >= lower_range then 0 else 1 end diff from sample_data)) group by attribute, grp; ID LOWER_RANGE UPPER_RANGE ATTRIBUTE ---------- ----------- ----------- --------- 1 10 30 A 3 40 55 A 4 15 35 BЭто означает, что нижняя строка текущей строки больше или равна верхнему диапазону предыдущей строки. Если это так, то мы устанавливаем результат равным 0, иначе мы будем устанавливать его равным 1 (что указывает на разрыв между двумя строками).
Затем мы выполняем суммарную сумму по всем строкам каждого атрибута. Тогда это будет иметь тот же результат для строк, которые перекрываются, и будет увеличиваться на 1 каждый раз, когда он сталкивается с пробелом.
Теперь мы можем использовать это вместе со столбцом атрибута для группировки строк и поиска их диапазонов min/max вместе с min (id).
stackoverrun.com
sql - Объединение строк SQL - Доступ
Если каждая строка имела уникальный идентификатор (Primary Key), это было бы намного проще. Тем не менее, вы работаете с данными, которые у вас есть, а не с данными, которые вы хотели бы иметь, так что здесь мой обходной способ его выполнения. Вы можете объединить все это в один запрос и не использовать временные таблицы; Я разделил это так, чтобы было удобно понимать, а не быть кратким.
Сначала извлеките самые высокие продажи для каждой комбинации Name-Week:
SELECT Name, Week, MAX(Sales) INTO #MaxSales FROM [YourTable] GROUP BY Name, WeekИспользуйте эту информацию, чтобы получить Менеджер, который вы должны использовать на каждую неделю (мы используем TOP 1, чтобы разрешить случай, когда два менеджера имеют одинаковые продажи для одного и того же имени/недели, я не уверен, как вы хотели бы это решить. ):
SELECT Name, Week, Manager INTO #MaxSalesManager FROM [YourTable] INNER JOIN #MaxSales ON [YourTable].Name = #MaxSales.Name AND [YourTable].Week = #MaxSales.Week WHERE [YourTable].Sales = #MaxSales.SalesТеперь вы можете извлечь необходимую информацию:
SELECT [YourTable].Name, [YourTable].Week, #MaxSalesManager.Manager, SUM([YourTable].Sales) FROM [YourTable] INNER JOIN #MaxSalesManager ON [YourTable].Name = #MaxSalesManager.Name AND [YourTable].Week = #MaxSalesManager.Week GROUP BY [YourTable].Name, [YourTable].Week, #MaxSalesManager.ManagerНадеюсь это поможет!
РЕДАКТИРОВАТЬ:
Объединяя их в один запрос:
SELECT [YourTable].Name, [YourTable].Week, #MaxSalesManager.Manager, SUM([YourTable].Sales) FROM [YourTable] INNER JOIN (SELECT Name, Week, Manager FROM [YourTable] INNER JOIN (SELECT Name, Week, MAX(Sales) FROM [YourTable] GROUP BY Name, Week) AS #MaxSales ON [YourTable].Name = #MaxSales.Name AND [YourTable].Week = #MaxSales.Week WHERE [YourTable].Sales = #MaxSales.Sales) AS #MaxSalesManager ON [YourTable].Name = #MaxSalesManager.Name AND [YourTable].Week = #MaxSalesManager.Week GROUP BY [YourTable].Name, [YourTable].Week, #MaxSalesManager.Managerqaru.site
Объединение нескольких значений строк в 1 строку, с SQL для iSeries Безопасный SQL
Во-первых, мне нужно поблагодарить Кенту Миллигана и его статью на http://www.mcpressonline.com/sql/techtip-combining-multiple-row-values-into-a-single-row-with-sql-in-db2- for-i.html за то, что у меня есть такая проблема, как у меня. Но теперь мне нужно расширить то, что он сделал здесь.
Чтобы избежать необходимости переходить к его статье, проблема, которую он рассматривал, заключалась в объединении строковых данных из нескольких строк в одну строку в результирующей таблице. Например:
Настольные автомобили:
- Сделать модель
- Ford Fusion
- Chevy Tahoe
- Honda Odyssey
- Ford Taurus
- Форд Фокус
- Chevy Malibu
Результаты:
- Сделать модель
- Чеви Малибу, Тахо
- Ford Focus, Телец, Fusion
- Honda Odyssey
Это было сделано с помощью инструкции SQL:
WITH numbered_sets(make, model, curr, prev) AS ( SELECT make, model, ROW_NUMBER() OVER (PARTITION BY make ORDER BY model) AS curr, ROW_NUMBER() OVER (PARTITION BY make ORDER BY model) -1 AS prev FROM inventory) SELECT make, MAX (TRIM(L ',' FROM CAST(SYS_CONNECT_BY_PATH(model, ',') AS VARCHAR(256)) )) FROM numbered_sets START WITH curr = 1 CONNECT BY make = PRIOR make AND prev = PRIOR curr GROUP BY makeЯ смог адаптировать это к своему столу и получить большую часть своего пути. Но для моих целей у меня есть дополнительная колонка, которую мне нужно включить для группировки. Например:
Настольные автомобили:
- Сделать модель типа
- Ford Sedan Fusion
- Chevy SUV Tahoe
- Honda Minivan Odyssey
- Ford Sedan Taurus
- Ford Sedan Focus
- Чеви Седан Малибу
- Внедорожник Ford
- Ford внедорожник Explorer
- Chevy Sedan Impala
Для результатов я бы искал:
- Сделать модель типа
- Чеви Седан Малибу, Импала
- Chevy SUV Tahoe
- Ford Sedan Fusion, Телец, Фокус
- Ford внедорожник Escape, Explorer
- Honda Minivan Odyssey
Есть ли у кого-нибудь мысли о том, что мне нужно добавить к исходному заявлению, чтобы иметь возможность добавить столбец ТИП и группу соответственно? Я пробовал несколько вещей, но я подозреваю, что мне нужно что-то сделать с утверждением CONNECT_BY_PATH, я просто не уверен, что.
спасибо
Solutions Collecting From Web of "Объединение нескольких значений строк в 1 строку, с SQL для iSeries"
Я думаю, вам просто нужно интегрировать тип в правильные точки, которые вызывают запрос.
не будучи в состоянии проверить, я думаю, что это будет близко; но я, возможно, что-то пропустил …
WITH numbered_sets(make, type, model, curr, prev) AS ( SELECT make, type, model, ROW_NUMBER() OVER (PARTITION BY make, Type ORDER BY Make, Type, model) AS curr, ROW_NUMBER() OVER (PARTITION BY make, type ORDER BY Make, type, model) -1 AS prev FROM inventory) SELECT make, Type MAX (TRIM(L ',' FROM CAST(SYS_CONNECT_BY_PATH(model, ',') AS VARCHAR(256)) )) FROM numbered_sets START WITH curr = 1 CONNECT BY make = PRIOR make AND prev = PRIOR curr and type = prior type GROUP BY make, typesql.fliplinux.com
sql - Объединение строк в SQL
Я записываю начало и время окончания SQL, когда что-то происходит с записью, в основном пользователь открывает экран, содержащий информацию о записи, и я хочу посмотреть, как долго экран был открыт.
Я записываю время начала, а конец вместе со сценой в данный момент находится в этом случае в связанной таблице, подобной этому:
| Id | Reference | Stage | StartTime | EndTime | | 1 | 123456789 | NEW | 2015-03-30 16:04:39.8100000 | NULL | | 2 | 123456789 | NEW | NULL | 2015-03-30 16:06:44.3830000 | | 3 | 123456789 | VAL | 2015-03-30 16:09:00.3800000 | NULL | | 4 | 123456789 | VAL | NULL | 2015-03-30 16:11:04.9870000 | | 5 | 123456789 | CAP | 2015-03-30 16:20:25.7900000 | NULL | | 6 | 123456789 | CAP | NULL | 2015-03-30 16:21:12.1130000 | | 7 | 123456789 | CAP | 2015-03-30 16:22:40.4930000 | NULL | | 8 | 123456789 | CAP | NULL | 2015-03-30 16:29:02.5030000 | | 9 | 123456789 | CAP | 2015-03-30 16:29:17.8970000 | NULL | | 10 | 123456789 | CAP | NULL | 2015-03-30 16:55:13.8870000 | | 11 | 123456789 | CAP | 2015-03-30 16:56:20.2230000 | NULL | | 12 | 123456789 | CAP | NULL | 2015-03-30 16:56:40.3830000 |qaru.site
SQL 2005 Слияние / объединение нескольких строк в один столбец Безопасный SQL
Я предпочитаю определять настраиваемый пользовательский агрегат. Вот пример UDA, который выполнит что-то очень близкое к тому, что вы просите.
Зачем использовать определяемую пользователем совокупность вместо вложенного SELECT? Это все о производительности и о том, что вы готовы мириться. Для небольшого количества элементов вы можете наверняка уйти с вложенным SELECT, но для большого «n» вы заметите, что в плане запроса по существу выполняется вложенный SELECT один раз для каждой строки в выходном списке. Это может быть поцелуй смерти, если вы говорите о большом количестве рядов. С UDA можно объединить эти значения за один проход.
Конечно, компромисс заключается в том, что UDA требует, чтобы вы использовали CLR для его развертывания, и это часто не так много людей. В Oracle эта конкретная ситуация немного лучше, так как вы можете напрямую использовать PL / SQL для создания своего пользовательского агрегата, но я отвлекаюсь …
попробуй это:
set nocount on; declare @t table (id char(36), x char(1)) insert into @t (id, x) select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'A' union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' set nocount off SELECT p1.id, stuff( (SELECT ' ' + x FROM @t p2 WHERE p2.id=p1.id ORDER BY id, x FOR XML PATH('') ) ,1,1, '' ) AS YourValues FROM @t p1 GROUP BY idВЫВОД:
id YourValues ------------------------------------ -------------- 61E77D90-D53D-4E2E-A09E-9D6F012EB59C ABCD 7ce953ca-a55b-4c55-a52c-9d6f012ea903 EF (2 row(s) affected)РЕДАКТИРОВАТЬ на основе комментария OP о необходимости выполнения существующего запроса, попробуйте следующее:
;WITH YourBugQuery AS ( --replace this with your own query select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' AS ColID , 'A' AS ColX union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' ) SELECT p1.ColID, stuff( (SELECT ' ' + ColX FROM YourBugQuery p2 WHERE p2.ColID=p1.ColID ORDER BY ColID, ColX FOR XML PATH('') ) ,1,1, '' ) AS YourValues FROM YourBugQuery p1 GROUP BY ColIDэто имеет те же результаты, что и выше.
Другой способ сделать это – использовать параметр FOR XML PATH
SELECT [ID], ( SELECT [Value] + ' ' FROM [YourTable] [YourTable2] WHERE [YourTable2].[ID] = [YourTable].[ID] ORDER BY [Value] FOR XML PATH('') ) [Values] FROM [YourTable] GROUP BY [YourTable].[ID]sql.fliplinux.com
SQL Query – Объединение результатов в одну строку MS SQL Server
У меня есть функция sql, которая включает этот код:
Мне нужно объединить все результаты из запроса select в CodeNameString.
Очевидно, что цикл FOREACH в коде C # будет делать это, но как это сделать в SQL?
Если вы работаете на SQL Server 2005 или выше, вы можете использовать этот FOR XML PATH & STUFF трюк:
DECLARE @CodeNameString varchar(100) SELECT @CodeNameString = STUFF( (SELECT ',' + CodeName FROM dbo.AccountCodes ORDER BY Sort FOR XML PATH('')), 1, 1, '')FOR XML PATH('') основном объединяет ваши строки вместе в один длинный XML-результат (что-то вроде ,code1,code2,code3 и т. Д.), А STUFF ставит символ «ничего» в первом ,code1,code2,code3 , например, излишняя "первая запятая, чтобы дать вам результат, который вы, вероятно, ищете.
UPDATE: ОК. Я понимаю комментарии – если ваш текст в таблице базы данных уже содержит символы типа < , > или & , тогда мое текущее решение фактически закодирует их в < , > , и & ,
Если у вас есть проблема с этим XML-кодированием – тогда да, вы должны посмотреть на решение, предложенное @KM, которое работает и для этих символов. Одно слово предупреждения от меня: этот подход намного более ресурсоемкий и интенсивный процесс – просто так вы знаете.
DECLARE @CodeNameString varchar(max) SET @CodeNameString='' SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort SELECT @CodeNameString@ Ответ AlexanderMP верен, но вы также можете рассмотреть вопрос об обработке нулей с coalesce :
declare @CodeNameString nvarchar(max) set @CodeNameString = null SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes select @CodeNameStringДля SQL Server 2005 и выше используйте Coalesce для numeric values nulls и я использую Cast или Convert, если есть numeric values –
declare @CodeNameString nvarchar(max) select @CodeNameString = COALESCE(@CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort select @CodeNameStringfrom msdn. Не используйте переменную в инструкции SELECT для объединения значений (то есть для вычисления совокупных значений). Возможны неожиданные результаты запроса. Это связано с тем, что все выражения в списке SELECT (включая присваивания) не гарантируются для выполнения только один раз для каждой строки вывода
Вышеприведенное кажется, что конкатенация, как сделано выше, недействительна, поскольку назначение может выполняться больше раз, чем есть строки, возвращаемые выбором
Вот еще один пример реальной жизни, который отлично работает как минимум с выпуском 2008 года (и позже).
Это исходный запрос, который использует простой max() для получения хотя бы одного из значений:
SELECT option_name, Field_M3_name, max(Option_value) AS "Option value", max(Sorting) AS "Sorted" FROM Value_list group by Option_name, Field_M3_name ORDER BY option_name, Field_M3_nameУлучшенная версия, где основным улучшением является то, что мы показываем все значения, разделенные запятыми:
SELECT from1.keys, from1.option_name, from1.Field_M3_name, Stuff((SELECT DISTINCT ', ' + [Option_value] FROM Value_list from2 WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE) .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Option values", Stuff((SELECT DISTINCT ', ' + CAST([Sorting] AS VARCHAR) FROM Value_list from2 WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE) .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Sorting" FROM ((SELECT DISTINCT COALESCE(Option_name,'') + '|' + COALESCE(Field_M3_name,'') AS keys, Option_name, Field_M3_name FROM Value_list) -- WHERE ) from1 ORDER BY keysОбратите внимание, что мы решили все возможные проблемы с NULL о которых я могу думать, а также мы исправили ошибку, которую мы получили для числовых значений (сортировка полей).
sqlserver.bilee.com