Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将多行聚合为新的单长行数据_Sql_Pivot_Aggregate - Fatal编程技术网

Sql 将多行聚合为新的单长行数据

Sql 将多行聚合为新的单长行数据,sql,pivot,aggregate,Sql,Pivot,Aggregate,我有一个数据库,每个案例有许多行数据。每个案例都有一个唯一的ID,但每行都有一个多选元素和一个值。显然,每次用户选择一个多选元素sce和新值时,都会有一个新行。唯一ID就像一个关键点,将所有行作为此实例的公共元素保存在一起 数据如下: UniqueID Value Text Username Contact -------------------------------------------------- 123456 No Sound Horn

我有一个数据库,每个案例有许多行数据。每个案例都有一个唯一的ID,但每行都有一个多选元素和一个值。显然,每次用户选择一个多选元素sce和新值时,都会有一个新行。唯一ID就像一个关键点,将所有行作为此实例的公共元素保存在一起

数据如下:

UniqueID  Value      Text       Username     Contact
--------------------------------------------------
123456    No Sound   Horn       Johnson      0788
123456    Broken     Headlight  Johnson      0788
123456    Broken     Windscreen Johnson      0788
我希望只保留一行数据、它们的用户详细信息、密钥唯一ID,然后为每个mce和每个值保留多个列

UniqueID Username  Contact   Text  Value      Text      Value   Text       Value
---------------------------------------------------------------------------------
123456   Johnson   0788      Horn  No Sound   Headlight Broken  Windscreen Broken
到目前为止,我已经基于唯一ID为每个mce使用update语句完成了这项工作,但作为存储过程,它有点笨重和冗长,可能需要相当长的时间才能运行

有谁能建议一个更好的方法吗


谢谢。

编辑2:我甚至不确定这是否可行,但我想我找到了一种方法。不幸的是,它非常黑客化,而且由于您从未发布过RDBMS标签,我甚至不知道它是否适用于您

正如我所说,我并不特别喜欢这个解决方案——我觉得它很笨拙,但它确实有效,我没有更多的时间专门讨论这个问题。除非其他人能想出一种方法使它更有效地工作,否则这是我能为你做的最好的事情。请注意,我创建并引用了一个名为Numbers的临时表,您需要它来保留在查询中。还请注意,您可能会得到比您想要的更多的列,但这将不得不保持

下面的脚本将允许您透视两列,保留第1列中的一个不同值和第2列中的多个值之间的关系

CREATE TABLE #Data (UniqueID INT, Value varchar(10), Txt varchar(10), Username varchar(10), Contact INT)
INSERT INTO #Data (UniqueID, Value, Txt, Username, Contact) 

SELECT 123456, 'No Sound', 'Horn', 'Johnson', 0788 UNION
SELECT 123456, 'Broken', 'Headlight', 'Johnson', 0788 UNION
SELECT 123456, 'Smashed', 'Headlight', 'Johnson', 0788 UNION
SELECT 123456, 'Shattered', 'Headlight', 'Johnson', 0788 UNION
SELECT 123456, 'Busted', 'Headlight', 'Johnson', 0788 UNION
SELECT 123456, 'Inop', 'Brake', 'Johnson', 0788 

DECLARE @sql AS varchar(max)
DECLARE @vpivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @vselect_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @tpivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @tselect_list AS varchar(max) -- Leave NULL for COALESCE technique



CREATE TABLE #Numbers (Number INT) 
;WITH NumberSequence( Number ) AS
  (
    SELECT 1 as Number
    UNION ALL 
    SELECT Number + 1
    FROM NumberSequence
    WHERE Number < 100
  )
INSERT INTO #Numbers (Number)
SELECT Number FROM NumberSequence




SELECT 
    @vpivot_list = COALESCE(@vpivot_list + ', ', '') + '[' + TxtValCombinations + ']'
FROM
  (
    SELECT 
        'T' + CAST(Txt.Number AS VARCHAR(5)) + '_' + 
        'V' + CAST(Val.Number AS VARCHAR(5))  AS TxtValCombinations
    FROM 
        #Numbers Txt
         INNER JOIN 
          (
            SELECT MAX(CountTxt) MaxCountTxt
            FROM
              (
                SELECT COUNT(DISTINCT Txt) CountTxt
                FROM #Data
                GROUP BY UniqueID 
              ) cv
          ) MaxCountTxt ON 
            Txt.Number <= MaxCountTxt.MaxCountTxt
         INNER JOIN 
        #Numbers Val ON 
            Val.Number < 
              (
                SELECT MAX(CountValue) MaxCountValue
                FROM
                  (
                    SELECT COUNT(Value) CountValue
                    FROM #Data
                    GROUP BY UniqueID, Txt
                  ) cv
              )
  ) PossibleValues


SELECT 
    @tpivot_list = COALESCE(@tpivot_list + ', ', '') + '[' + TxtCombinations + ']'
FROM
  (
    SELECT 
        'T' + CAST(Txt.Number AS VARCHAR(5)) AS TxtCombinations
    FROM 
        #Numbers Txt
         INNER JOIN 
          (
            SELECT MAX(CountTxt) MaxCountTxt
            FROM
              (
                SELECT COUNT(DISTINCT Txt) CountTxt
                FROM #Data
                GROUP BY UniqueID 
              ) cv
          ) MaxCountTxt ON 
            Txt.Number <= MaxCountTxt.MaxCountTxt
  ) PossibleValues

SELECT @vselect_list = STUFF(
  (
    SELECT',' + 
        'T' + CAST(Txt.Number AS VARCHAR(5)) + '_' + 
        'V' + CAST(Val.Number AS VARCHAR(5))  --AS TxtValCombinations
    FROM 
        #Numbers Txt
         INNER JOIN 
          (
            SELECT MAX(CountTxt) MaxCountTxt
            FROM
              (
                SELECT COUNT(DISTINCT Txt) CountTxt
                FROM #Data
                GROUP BY UniqueID 
              ) cv
          ) MaxCountTxt ON 
            Txt.Number <= MaxCountTxt.MaxCountTxt
         INNER JOIN 
        #Numbers Val ON 
            Val.Number < 
              (
                SELECT MAX(CountValue) MaxCountValue
                FROM
                  (
                    SELECT COUNT(Value) CountValue
                    FROM #Data
                    GROUP BY UniqueID, Txt
                  ) cv
              )
    ORDER BY Txt.Number, Val.Number
     FOR XML PATH(''), type
        ).value('.', 'varchar(max)'), 1, 1, '')

 SELECT @tselect_list = STUFF(
  (

    SELECT TxtValCombinations
    FROM 
     (
        SELECT',MAX(' + 
            'T' + CAST(Txt.Number AS VARCHAR(5)) + '_' + 
            'V' + CAST(Val.Number AS VARCHAR(5)) + ') AS '+ 
            'T' + CAST(Txt.Number AS VARCHAR(5)) + '_' + 
            'V' + CAST(Val.Number AS VARCHAR(5))  AS TxtValCombinations
        FROM 
            #Numbers Txt
             INNER JOIN 
              (
                SELECT MAX(CountTxt) MaxCountTxt
                FROM
                  (
                    SELECT COUNT(DISTINCT Txt) CountTxt
                    FROM #Data
                    GROUP BY UniqueID 
                  ) cv
              ) MaxCountTxt ON 
                Txt.Number <= MaxCountTxt.MaxCountTxt
             INNER JOIN 
            #Numbers Val ON 
                Val.Number < 
                  (
                    SELECT MAX(CountValue) MaxCountValue
                    FROM
                      (
                        SELECT COUNT(Value) CountValue
                        FROM #Data
                        GROUP BY UniqueID, Txt
                      ) cv
                  )

        UNION ALL 
        SELECT',MAX(' + 
            'T' + CAST(Txt.Number AS VARCHAR(5)) +') AS T' + CAST(Txt.Number AS VARCHAR(5))  --AS TxtValCombinations
        FROM 
            #Numbers Txt
             INNER JOIN 
              (
                SELECT MAX(CountTxt) MaxCountTxt
                FROM
                  (
                    SELECT COUNT(DISTINCT Txt) CountTxt
                    FROM #Data
                    GROUP BY UniqueID 
                  ) cv
              ) MaxCountTxt ON 
                Txt.Number <= MaxCountTxt.MaxCountTxt

     ) s
        ORDER BY TxtValCombinations
     FOR XML PATH(''), type
        ).value('.', 'varchar(max)'), 1, 1, '')



SET @sql = '

SELECT UniqueID, Username, Contact, ' + @tselect_list + '
FROM 
  (

    SELECT UniqueID, Username, Contact, Txt, tPIVOT_CODE, ' + @vselect_list + '
    FROM 
      (
        SELECT b.UniqueID, Value, Username, Contact, Txt, tPIVOT_CODE, vPIVOT_CODE
        FROM 
              (
                SELECT 
                    Data.UniqueID,  
                    Data.Username, 
                    Data.Contact, 
                    Data.Txt,
                    ''T'' + CAST(grpTxt.TxtNum AS VARCHAR(5)) AS tPIVOT_CODE, 
                    Data.Value,
                    ''T'' + CAST(grpTxt.TxtNum AS VARCHAR(5)) + ''_V'' + CAST(ROW_NUMBER() OVER (PARTITION BY Data.UniqueID, Data.Txt ORDER BY Data.Value) AS VARCHAR(4)) vPIVOT_CODE 
                FROM 
                    #Data Data
                     INNER JOIN 
                      (
                        SELECT UniqueID, Txt, ROW_NUMBER() OVER (PARTITION BY UniqueID ORDER BY Txt) AS TxtNum
                        FROM #Data
                        GROUP BY UniqueID, Txt
                      ) grpTxt ON 
                        Data.UniqueID = grpTxt.UniqueID AND
                        Data.Txt = grpTxt.Txt

              ) b
      ) vp
    PIVOT (
        MIN(Value)
        FOR vPIVOT_CODE IN (
            ' + @vpivot_list + '
        )
    ) AS vpvt
  ) tp
PIVOT (
    MIN(Txt)
    FOR tPIVOT_CODE IN (
        ' + @tpivot_list + '
    )
) AS tpvt
GROUP BY UniqueID, UserName, Contact
ORDER BY UniqueID, UserName, Contact
'


--PRINT @sql
--PRINT @tselect_list
--PRINT @vpivot_list
EXEC (@sql)

DROP TABLE #Data
DROP TABLE #Numbers 

请发布您的表结构、一些现有数据以及希望输出的示例。谢谢,currentlysimplified:UNiqueID、Value、MCE、用户名、Contact…尝试编辑文章以包含它:如果您需要帮助,请查看这篇文章的做法。@AHiggins-感谢您的指导,我至少今天学到了一些东西!请通过添加适当的标记Oracle、SQL Server、MySQL等来指定目标RDBMS。。可能有一些答案利用了并非普遍支持的语言或产品功能。此外,通过使用特定的RDBMS标记它,您的问题可能会得到更适合回答它的人的注意。Thankyou@ahiggins我的实际数据有18列需要透视的缺陷,我说的=sql部分是静态的,=pivot_列表是要聚合的部分对吗?谢谢您的帮助。是的,pivot_列表是要聚合的列-在这段代码中,它基本上只读取r1、r2、r3等,一直到特定uniqueID的最大值。您是说总共有18个列需要聚合,而不是示例中的两个Value+Txt,还是说Value+Txt最多可以有18行???只有一个文本列,但在提交到数据库的表单上,可以最多选择18次多选元素值,这意味着在第一个实例中最多可以有18行,每行的唯一区别是值字段,除非您知道要选择的唯一ID,否则很难显示结果,所以这就是将18行精简为更长的一行背后的想法。那么,Txt+18 x valueSo,在你想要的输出中,你可以有UniqueID,Txt,Value1,Value2,等等。?或者您正在寻找UniqueID、Txt1、Value11、Value12、Txt2、Value21、Value22?是的,唯一ID、Txt、Value1、Value2、Value3…Value18。更新我一直在使用输入UniqueID,然后更新每个列以适应。你认为在SSI内部运行会更容易吗。