尝试在SSMS中将多个列和行与单个查询组合在一起。这是我正在使用的更复杂的表的更简单版本:
这是我当前的查询:
CREATE TABLE Table1
([C1] varchar(50), [C2] varchar(50), [C3] varchar(50))
;
INSERT INTO Table1
([C1], [C2], [C3])
VALUES
('F92', 'Game1', 'b100'),
('F92', 'Game1', 'b200'),
('F92', 'Game2', 'C200'),
('F92', 'Game2', 'D400')
;
SELECT
C1,C2,
STUFF(
(SELECT ', ' + C3
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2
FOR XML PATH (''))
, 1, 1, '') AS NamesList
FROM Table1 AS a
GROUP BY C1,C2
drop table table1
我打算把结果作为:
C1 | Namelist
F92 | Game1 b100, b200 Game2 c200, d400
这在单个查询中是可行的吗?
答案 0 :(得分:0)
当然可以这样做。您可以使用cte获取您已经获得的分隔列表。然后获取结果并将其转换为另一个分隔列表。但是你可能想要一些除了空格之外的组之间的分隔符。
with FirstPass as
(
SELECT
C1,
C2 + ' ' + STUFF(
(SELECT ', ' + C3
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2
FOR XML PATH (''))
, 1, 1, '') AS NamesList
FROM Table1 AS a
GROUP BY C1,C2
)
select C1
, NameList = stuff((select ' ' + fp2.NamesList
from FirstPass fp2
where fp.C1 = fp2.C1
FOR XML PATH('')), 1, 1, '')
from FirstPass fp
group by fp.C1
返回:
F92 | Game1 b100,b200 Game2 C200,D400
- 编辑 -
由于需要按计数对C2进行排序的新要求,您只需添加一点聚合即可。这与原版没有太大关系。
with FirstPass as
(
SELECT
C1,
C2 + ' ' + STUFF(
(SELECT ', ' + C3
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2
FOR XML PATH (''))
, 1, 1, '') AS NamesList
, count(*) as GameCount
FROM Table1 AS a
GROUP BY C1,C2
)
select distinct C1
, NameList = stuff((select ' ' + fp2.NamesList
from FirstPass fp2
where fp.C1 = fp2.C1
group by fp2.GameCount, fp2.NamesList
order by fp2.GameCount desc
FOR XML PATH('')), 1, 1, '')
from FirstPass fp
答案 1 :(得分:0)
说现在的值是
VALUES
('F92', 'Game1', 'b100'),
('F92', 'Game1', 'b200'),
('F92', 'Game2', 'C200'),
('F92', 'Game2', 'D400'),
('F92', 'Game2', 'D500')
;
所以现在Game2出现了3次。使用Sean Lange的代码结果按升序排列,因此Game1在Game2之前出现。有没有办法根据列c2的数量(降序)显示结果,因此预期的结果将是
F92 | Game2 C200, D400, D500 Game1 b100, b200
答案 2 :(得分:0)
扩展此示例。这是新查询:
CREATE TABLE Table1
([C1] varchar(50), [C2] varchar(50), [C3] varchar(50),[C4] varchar(50),[C5] varchar(50) )
;
INSERT INTO Table1
([C1], [C2], [C3], [C4], [C5])
VALUES
('F92', 'XBOX','81-94','Game1', 'B350'),
('F92', 'XBOX','81-94','Game1', 'B150'),
('F92', 'XBOX','76-80','Game2', 'PB100'),
('F92', 'XBOX','76-80','Game2', 'PB200'),
('F92', 'XBOX','95-97','Game2', 'PB300')
;
with FirstPass as
(
SELECT
C1, c2,
c3 + ' ' + c4+ + STUFF(
(SELECT ', ' +''+ c5
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2 AND C3 = a.C3 AND C4 = a.C4
FOR XML PATH (''))
, 1, 1, '') AS NamesList
, count(*) as GameCount
FROM Table1 AS a
GROUP BY C1,C2,c3, c4
)
select distinct C1,C2
, NameList = stuff((select ' ' + fp2.NamesList
from FirstPass fp2
where fp.C1 = fp2.C1
group by fp2.GameCount, fp2.NamesList
order by fp2.GameCount
FOR XML PATH('')), 1, 1, '')
into table2
from FirstPass fp
-- concatenate and insert into existing table
insert into table2 (C1, conc)
select C1, C2 + ' ' + NameList
from FirstPass fp
SELECT * FROM table2
drop table table1
drop table table2
期望的结果:
C1 |conc
F92 |XBOX 95-97 GAME2 PB300 76-80 GAME2 PB100, PB200 81-94 GAME1 B350, B150
并将此结果插入现有表“table2”
在这里连接最佳解决方案是否达到了预期效果?这部分问题让我失望:
-- concatenate and insert into existing table
insert into table2 (C1, conc)
select C1, C2 + ' ' + NameList
from FirstPass fp