我知道标题是暧昧的,我知道这里有类似的问题。我看起来并没能完全按照我的需要做任何事情。
我需要Group By ReportNumber和共享一个类别的人添加到一个单元格。
我的数据库:
ID | CategorySymbol | ReportNumber | NumberInCategory
1 A 31 101
2 B 31 107
3 C 31 121
4 A 32 191
5 A 33 165
6 B 32 156
7 C 32 127
8 A 31 166
9 B 31 177
期望的结果:
ReporNumber | CategoryA | CategoryB | CategoryC
31 **101,166** **107,177** 121
32 191 156 127
33 165 NULL NULL
许多不同尝试之一:
select ReportNumber,
CategoryFirst, CategorySecond, CategoryThird, CategoryFourth
from
(
select NumberInCategory, Report.value('(/Report/@ReportNumber)[1]', 'nvarchar(max)') AS ReportNumber,
'Category' + cast(CategorySymbol as varchar(10)) CategorySymbol
from dbo.ReportDB t
) d
pivot
(
max(NumberInCategory)
for CategorySymbol in (CategoryFirst, CategorySecond, CategoryThird, CategoryFourth)
) piv;
我的结果:
ReporNumber | CategoryA | CategoryB | CategoryC
31 **166** **177** 121
32 191 156 127
33 165 NULL NULL
很明显为什么结果是这样的 - max(NumberInCategory)。唯一的问题是如何根据for循环中的CategorySymbol进行选择Number的查询。我尝试做一些功能,返回一个结果,如STUFF或简单的SELECT,但无法正确执行。它不允许我替换max(NumberInCategory)。
E.g。类似的东西:
STUFF((SELECT ', ' + CAST(NumberInCategory AS VARCHAR(10)) [text()], Report.value('(/Report/@ReportNumber)[1]', 'nvarchar(max)') AS ReportNumber
FROM ReportDB
WHERE ReportNumber = t.ReportNumber
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') List_Output
答案 0 :(得分:6)
在pivot()
之前使用stuff()
with select ... for xml path ('')
method of string concatenation:
;with t as (
select
NumberInCategory
, Report.value('(/Report/@ReportNumber)[1]', 'nvarchar(max)') AS ReportNumber
, CategorySymbol
from dbo.ReportDB
)
select ReportNumber, CategoryA, CategoryB, CategoryC
from (
select
t.ReportNumber
, CategorySymbol = 'Category'+convert(varchar(10),t.CategorySymbol)
, NumberInCategory = stuff((
select ', '+convert(varchar(13),i.NumberInCategory)
from t i
where i.ReportNumber = t.ReportNumber
and i.CategorySymbol = t.CategorySymbol
order by i.NumberInCategory
for xml path (''), type).value('(./text())[1]','nvarchar(max)')
,1,2,'')
from t
group by t.ReportNumber, t.CategorySymbol
) s
pivot (max(NumberInCategory)
for CategorySymbol in (CategoryA, CategoryB, CategoryC)
) piv;
rextester演示:http://rextester.com/OSAZ69656
返回:
+--------------+-----------+-----------+-----------+
| ReportNumber | CategoryA | CategoryB | CategoryC |
+--------------+-----------+-----------+-----------+
| 31 | 101, 166 | 107, 177 | 121 |
| 32 | 191 | 156 | 127 |
| 33 | 165 | NULL | NULL |
+--------------+-----------+-----------+-----------+
答案 1 :(得分:1)
这是一种略有不同的味道......
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
ID INT NOT NULL PRIMARY KEY CLUSTERED,
CategorySymbol CHAR(1) NOT NULL,
ReportNumber int NOT NULL,
NumberInCategory INT NOT NULL
);
INSERT #TestData(ID, CategorySymbol, ReportNumber, NumberInCategory) VALUES
(1, 'A', 31, 101),
(2, 'B', 31, 107),
(3, 'C', 31, 121),
(4, 'A', 32, 191),
(5, 'A', 33, 165),
(6, 'B', 32, 156),
(7, 'C', 32, 127),
(8, 'A', 31, 166),
(9, 'B', 31, 177);
-- SELECT * FROM #TestData td;
--==================================================================================
SELECT
td1.ReportNumber,
CategoryA = MAX(CASE WHEN td1.CategorySymbol = 'A' THEN STUFF(c.CSV, 1, 1, '') END),
CategoryB = MAX(CASE WHEN td1.CategorySymbol = 'B' THEN STUFF(c.CSV, 1, 1, '') END),
CategoryC = MAX(CASE WHEN td1.CategorySymbol = 'C' THEN STUFF(c.CSV, 1, 1, '') END)
FROM
#TestData td1
CROSS APPLY (
(SELECT
CONCAT(',', td2.NumberInCategory)
FROM
#TestData td2
WHERE
td1.CategorySymbol = td2.CategorySymbol
AND td1.ReportNumber = td2.ReportNumber
FOR XML PATH(''))
) c (CSV)
GROUP BY
td1.ReportNumber;
结果...
ReportNumber CategoryA CategoryB CategoryC
------------ ---------- ---------- ----------
31 101,166 107,177 121
32 191 156 127
33 165 NULL NULL