如何从一列插入多行

我想在一列中插入多行。

对于我这样的POS系统。

A

 Transaction ID| Item Code|Qty|Total|Transaction Date| ----------------------------------------------------- 00001 | Item 1 |3 |100 |12/07/2014 | 00001 | Item 2 |2 |50 |12/07/2014 | 00001 | Item 3 |1 |150 |12/07/2014 | 

之后我想在我的桌子上看到这个

 Transaction ID|Item Code |Total of Qty|Total of Price|Transaction Date| ----------------------------------------------------------------------------------- 00001 |Item 1, Item 2, Item 3| 6 | 150 | 12/07/2014 | 

使用GROUP_CONCAT在GROUP BY中将字符串连接在一起:

 SELECT TransactionID, GROUP_CONCAT(ItemCode) AS ItemCodes, SUM(Qty) AS TotalofQty, SUM(Total) AS TotalPrice, TransactionDate FROM TableA GROUP BY TransactionID, TransactionDate; 

SqlFiddle在这里

编辑将RDBMS更改为SqlServer后,需要进行修复以补偿SqlServer缺少字符串折叠function(如GROUP_CONCAT 。 这是STUFF / FOR XML PATH之一:

 SELECT a.[Transaction ID], STUFF(( SELECT ',' + [Item Code] FROM TableA WHERE [Transaction ID] = a.[Transaction ID] FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS ItemCodes, SUM(Qty) AS TotalofQty, SUM(Total) AS TotalPrice, [Transaction Date] FROM TableA a GROUP BY a.[Transaction ID], a.[Transaction Date]; 

请注意,您需要手动将STUFF subquery与相应的外部查询相关联。

SqlServer小提琴

确实SQL Server中没有内置的concat函数,我怀疑会有这样的。 原因是创建CLR用户定义聚合非常容易。 实际上,MSDN上已有这样的例子。 您可以在此处找到创建GROUP_CONCAT函数所需的一切 – 字符串实用程序函数 。

基本上,您需要按照以下步骤操作:

  1. 启用CLR集成:

     sp_configure 'clr enabled', 1 GO RECONFIGURE GO 
  2. 创建以下C#类并构建.dll

     [Serializable] [Microsoft.SqlServer.Server.SqlUserDefinedAggregate( Microsoft.SqlServer.Server.Format.UserDefined, //use clr serialization to serialize the intermediate result IsInvariantToNulls = true,//optimizer property IsInvariantToDuplicates = false,//optimizer property IsInvariantToOrder = false,//optimizer property MaxByteSize = 8000)] //maximum size in bytes of persisted value public class Concatenate : Microsoft.SqlServer.Server.IBinarySerialize { ///  /// The variable that holds the intermediate result of the concatenation ///  private StringBuilder intermediateResult; ///  /// Initialize the internal data structures ///  public void Init() { intermediateResult = new StringBuilder(); } ///  /// Accumulate the next value, nop if the value is null ///  ///  public void Accumulate(SqlString value) { if (value.IsNull) { return; } intermediateResult.Append(value.Value).Append(','); } ///  /// Merge the partially computed aggregate with this aggregate. ///  ///  public void Merge(Concatenate other) { intermediateResult.Append(other.intermediateResult); } ///  /// Called at the end of aggregation, to return the results of the aggregation ///  ///  public SqlString Terminate() { string output = string.Empty; //delete the trailing comma, if any if (intermediateResult != null && intermediateResult.Length > 0) output = intermediateResult.ToString(0, intermediateResult.Length - 1); return new SqlString(output); } public void Read(BinaryReader r) { if (r == null) throw new ArgumentNullException("r"); intermediateResult = new StringBuilder(r.ReadString()); } public void Write(BinaryWriter w) { if (w == null) throw new ArgumentNullException("w"); w.Write(intermediateResult.ToString()); } } 
  3. 部署程序集并创建函数:

     DECLARE @SamplePath nvarchar(1024) SET @SamplePath = 'C:\MySample\' CREATE ASSEMBLY [StringUtils] FROM @SamplePath + 'StringUtils.dll' WITH permission_set = Safe; GO CREATE AGGREGATE [dbo].[Concatenate](@input nvarchar(4000)) RETURNS nvarchar(4000) EXTERNAL NAME [StringUtils].[Concatenate]; GO 

然后您可以将此函数用作任何标准聚合函数:

 SELECT TransactionID, [dbo].Concatenate(ItemCode) AS ItemCodes, SUM(Qty) AS TotalofQty, SUM(Total) AS TotalPrice, TransactionDate FROM TableA GROUP BY TransactionID, TransactionDate; 

注意,我已经了解CLR集成多年,但几个月前就开始使用它了。 当您处理大量数据时,性能差异很大。