Объединение нескольких строк строки в одну строку [duplicate]

Я думаю, что проблема связана с R. Я могу с радостью загрузить файлы UTF-8 или файлы UCS-2LE со многими не-ASCII-символами. Но некоторые символы приводят к сбою. Например, следующие

danish <- function() print("Skønt H. C. Andersens barndomsomgivelser var meget fattige, blev de i hans rige fantasi solbeskinnede.")
croatian <- function() print("Dodigović. Kako se Vi zovete?")
new_testament <- function() print("Ne provizu al vi trezorojn sur la tero, kie tineo kaj rusto konsumas, kaj jie ŝtelistoj trafosas kaj ŝtelas; sed provizu al vi trezoron en la ĉielo")
russian <- function() print ("Американские суда находятся в международных водах. Япония выразила серьезное беспокойство советскими действиями.")

хороши как в UTF-8, так и в UCS-2LE без русской линии. Но если это включено, то это терпит неудачу. Я указываю пальцем на R. Ваш китайский текст также кажется слишком сложным для R в Windows.

Locale кажется здесь неактуальным. Это всего лишь файл, вы говорите ему, что кодирует файл, почему ваш язык имеет значение?

318
задан Salman A 4 February 2018 в 19:21
поделиться

10 ответов

SQL Server 2017 вводит новую агрегатную функцию

STRING_AGG ( expression, separator) .

Объединяет значения строковых выражений и значений разделителей мест между ними. Сепаратор не добавляется в конце строки.

Конкатенированные элементы можно упорядочить, добавив WITHIN GROUP (ORDER BY some_expression)

. Для версий 2005-2016 я обычно использую XML метод в принятом ответе.

Однако это может быть неудачным при некоторых обстоятельствах. например если данные, которые будут конкатенированы, содержат CHAR(29), вы видите

FOR XML не может сериализовать данные ... потому что он содержит символ (0x001D), который не разрешен в XML.

Более надежным методом, который может обрабатывать все символы, будет использование агрегата CLR. Однако применение этого подхода к сложным элементам сложнее.

Метод присвоения переменной не гарантируется и его следует избегать в производственном коде.

156
ответ дан Martin Smith 15 August 2018 в 22:17
поделиться
  • 1
    Этот пример работал для меня, но я попытался сделать еще одну агрегацию, и это не сработало, дало мне ошибку: «имя корреляции« pre_trimmed »указано несколько раз в предложении FROM. & Quot; – PhilChuang 22 January 2010 в 20:24
  • 2
    'pre_trimmed' - это просто псевдоним для подзапроса. Псевдонимы необходимы для подзапросов и должны быть уникальными, поэтому для другого подзапроса изменить его к чему-то уникальному ... – Koen 12 March 2012 в 18:57
  • 3
    Это также доступно теперь в Azure SQL: azure.microsoft.com/en-us/roadmap/… – Simon_Weaver 14 September 2017 в 04:01
  • 4
    вы можете показать пример без имени table_name в качестве имени столбца, который запутан. – S.Mason 17 November 2017 в 22:47
156
ответ дан Martin Smith 5 September 2018 в 22:00
поделиться

Чтобы соединить имена всех менеджеров проектов с проектами, которые имеют несколько менеджеров проектов, пишите:

SELECT a.project_id,a.project_name,Stuff((SELECT N'/ ' + first_name + ', '+last_name FROM projects_v 
where a.project_id=project_id
 FOR
 XML PATH(''),TYPE).value('text()[1]','nvarchar(max)'),1,2,N''
) mgr_names
from projects_v a
group by a.project_id,a.project_name
6
ответ дан bluish 15 August 2018 в 22:17
поделиться

Взгляните на проект GROUP_CONCAT в Github, я думаю, что выполняю именно то, что вы ищете:

Этот проект содержит набор SQLCLR User- (SQLCLR UDA), которые совместно предлагают аналогичную функциональность функции MySQL GROUP_CONCAT. Существует множество функций для обеспечения максимальной производительности на основе требуемой функциональности ...

27
ответ дан Cullub 15 August 2018 в 22:17
поделиться
  • 1
    Почему нисходящий? Пожалуйста, объясни... – MaxiWheat 5 August 2014 в 21:46
  • 2
    Я использовал это, и он работает до сих пор. – Gary Brunton 1 October 2014 в 17:55
  • 3
    @MaxiWheat: многие ребята не читают вопрос или не отвечают, прежде чем нажать кнопку голосования. Это влияет на сообщение владельца напрямую из-за их ошибки. – Tai Phat Lam 30 October 2015 в 09:17

С приведенным ниже кодом вы должны установить PermissionLevel = External в своих свойствах проекта перед развертыванием и изменить базу данных на доверительный внешний код (не забудьте прочитать в другом месте об угрозах безопасности и альтернативах [например, сертификатах]), выполнив команду «ALTER DATABASE database_name SET TRUSTWORTHY ON ".

using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.SqlServer.Server;

[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined,
MaxByteSize=8000,
IsInvariantToDuplicates=true,
IsInvariantToNulls=true,
IsInvariantToOrder=true,
IsNullIfEmpty=true)]
    public struct CommaDelimit : IBinarySerialize
{


[Serializable]
 private class StringList : List<string>
 { }

 private StringList List;

 public void Init()
 {
  this.List = new StringList();
 }

 public void Accumulate(SqlString value)
 {
  if (!value.IsNull)
   this.Add(value.Value);
 }

 private void Add(string value)
 {
  if (!this.List.Contains(value))
   this.List.Add(value);
 }

 public void Merge(CommaDelimit group)
 {
  foreach (string s in group.List)
  {
   this.Add(s);
  }
 }

 void IBinarySerialize.Read(BinaryReader reader)
 {
    IFormatter formatter = new BinaryFormatter();
    this.List = (StringList)formatter.Deserialize(reader.BaseStream);
 }

 public SqlString Terminate()
 {
  if (this.List.Count == 0)
   return SqlString.Null;

  const string Separator = ", ";

  this.List.Sort();

  return new SqlString(String.Join(Separator, this.List.ToArray()));
 }

 void IBinarySerialize.Write(BinaryWriter writer)
 {
  IFormatter formatter = new BinaryFormatter();
  formatter.Serialize(writer.BaseStream, this.List);
 }
    }

Я тестировал это, используя запрос, который выглядит так:

SELECT 
 dbo.CommaDelimit(X.value) [delimited] 
FROM 
 (
  SELECT 'D' [value] 
  UNION ALL SELECT 'B' [value] 
  UNION ALL SELECT 'B' [value] -- intentional duplicate
  UNION ALL SELECT 'A' [value] 
  UNION ALL SELECT 'C' [value] 
 ) X 

И дает: A, B, C, D

6
ответ дан GregTSmith 15 August 2018 в 22:17
поделиться

Возможно, слишком поздно, чтобы принести пользу сейчас, но разве это не самый простой способ сделать что-то?

SELECT     empName, projIDs = replace
                          ((SELECT Surname AS [data()]
                              FROM project_members
                              WHERE  empName = a.empName
                              ORDER BY empName FOR xml path('')), ' ', REQUIRED SEPERATOR)
FROM         project_members a
WHERE     empName IS NOT NULL
GROUP BY empName
43
ответ дан J Hardiman 15 August 2018 в 22:17
поделиться
  • 1
    Интересно. Я уже закончил проект, но я попробую этот метод. Благодаря! – DanM 25 February 2010 в 17:59
  • 2
    Хороший трюк - проблема только для фамилий с пробелами, она заменит пространство разделителем. – Mark Elliot 14 July 2010 в 17:16
  • 3
    Я сам столкнулся с такой проблемой, Марк. К сожалению, до тех пор, пока MSSQL не получит время и не представит GROUP_CONCAT, это будет наименьший из накладных методов, которые я смог придумать для того, что здесь необходимо. – J Hardiman 26 July 2010 в 02:40
  • 4
    Спасибо за это! Вот скрипт SQL, показывающий, что он работает: sqlfiddle.com / #! 6 / c5d56 / 3 – fleed 25 September 2015 в 10:30

Пробовал эти, но для моих целей в MS SQL Server 2005 следующее было наиболее полезным, которое я нашел в xaprb

declare @result varchar(8000);

set @result = '';

select @result = @result + name + ' '

from master.dbo.systypes;

select rtrim(@result);

@Mark, как вы упомянули, это был космический характер, который вызвал проблемы для меня.

6
ответ дан Johan 15 August 2018 в 22:17
поделиться

Возможно, я немного опаздываю на вечеринку, но этот метод работает для меня и проще, чем метод COALESCE.

SELECT STUFF(
             (SELECT ',' + Column_Name 
              FROM Table_Name
              FOR XML PATH (''))
             , 1, 1, '')
153
ответ дан Mitch Wheat 15 August 2018 в 22:17
поделиться
  • 1
    Это только показывает, как concat values ​​- group_concat объединяет их по группам, что является более сложным (и то, что, по-видимому, требуется OP). См. Принятый ответ SO 15154644, как это сделать - предложение WHERE является критическим дополнением – DJDave 11 January 2018 в 14:26

О ответе Дж. Хардимана, как насчет:

SELECT empName, projIDs=
  REPLACE(
    REPLACE(
      (SELECT REPLACE(projID, ' ', '-somebody-puts-microsoft-out-of-his-misery-please-') AS [data()] FROM project_members WHERE empName=a.empName FOR XML PATH('')), 
      ' ', 
      ' / '), 
    '-somebody-puts-microsoft-out-of-his-misery-please-',
    ' ') 
  FROM project_members a WHERE empName IS NOT NULL GROUP BY empName

Кстати, это использование «Фамилии» опечатки или я не понимаю понятия здесь?

В любом случае, спасибо, много парней, потому что это спасло меня довольно долго:)

4
ответ дан user422190 15 August 2018 в 22:17
поделиться
  • 1
    Скорее недружественный ответ, если вы спросите меня и совсем не полезны в качестве ответа. – Tim Meers 20 March 2012 в 04:04
  • 2
    только видя это сейчас ... Я не имел в виду это в средстве, в то время, когда я был очень расстроен сервером sql (все-таки я). ответы на этот пост действительно были полезны на самом деле; EDIT: почему это не было полезно кстати? он сделал трюк для меня – user422190 4 June 2013 в 16:43
0
ответ дан Saugat Acharya 29 October 2018 в 05:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: