我有一个数据库,每个" case"有很多行数据。每个"案例"具有唯一的ID,但每行都有一个" multiple-choice-element"和"价值"。每当用户选择多个选择元素之一(mce)和新值时,显然会有一个新行。唯一ID就像一个linchpin,将所有行保存在一起作为此实例的公共元素
数据如下:
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的更新语句来完成此操作,但它有点笨拙且长时间作为存储过程,并且可能需要相当长的时间才能运行。 / p>
请有人建议更好的方式。
谢谢。
答案 0 :(得分:0)
我并不是特别喜欢这个解决方案,就像我说的那样 - 这对我来说很笨拙,但确实有效,而且我没有时间专心致志这个问题。除非别人能找到一种方法让它更有效地工作,否则这是我能为你做的最好的事情。请注意,我创建并引用了一个名为#Numbers的临时表 - 您需要将其保留在查询中。另请注意,您可能会得到比您想要的更多的列,但这必须保留。
以下脚本允许您转动两列,保留第1列(Txt)中不同值与第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