使用STUFF的问题

时间:2016-06-24 20:13:30

标签: sql sql-server

为什么这不起作用???似乎跟随我在这里发现的一切。我收到错误: 列'#TempTable.clientId'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

如果我将tt.clientId添加到组中,那么它不会执行这些操作,并将它们全部组合成一行,它们将作为单独的行出现。我输了一个错字吗?

SELECT tt.Station, STUFF((SELECT ', ' + c.client_code 
    FROM client c 
    WHERE tt.clientId = c.ID 
    FOR XML PATH('')),1,1,'') [Values]            
FROM #TempTable tt
GROUP BY tt.Station

3 个答案:

答案 0 :(得分:1)

您必须将tt.ClientId添加到GROUP BY,因为您使用它来关联子查询:WHERE tt.clientId = c.ID

否则,SQL Server如何知道每个Station使用哪个ClientId?

如果您不想按ClientId进行分组,则必须通过tt.Station进行关联。

答案 1 :(得分:1)

Model应该是SELECT ... FOR XML PATH列[s]的函数  在你的情况下GROUP BY。 像这样的东西

tt.station

答案 2 :(得分:1)

这里有几种选择,但有些事情需要考虑:

  1. 确定您最想要的项目是什么 - 在这种情况下,它看起来应该是station。如果是这种情况,接近它的一种方法是首先获得不同的站点集。这可以使用group by或distinct来完成。
  2. 确定要为其生成列表的项目级别 - 在这种情况下,它是client_code。因此,您希望让内部选择达到该级别。一种方法是在尝试使用xml之前解析不同的客户端代码集。
  3. 一个批评 - 提供一组简单的数据总是好的。使提供答案更容易,更快。

    同样,这里有替代方案,但这是一个可能的解决方案。

    测试数据

    select top (100)
        client_id = abs(checksum(newid())) % 100,
        client_code = char(abs(checksum(newid())) % 10 + 65)
    into #client
    from sys.all_columns a
    cross join sys.all_columns b;
    
    select top (100)
        station = abs(checksum(newid())) % 10,
        client_id = abs(checksum(newid())) % 50 -- just a subset
    into #temp
    from sys.all_columns a
    cross join sys.all_columns b;
    

    查询

    select station, client_codes = stuff((
        select ', ' + cc.client_code
        from (
            select distinct c.client_code -- distinct client codes
            from #temp t
            join #client c
                on t.client_id = c.client_id
            where t.station = s.station) cc
        order by client_code
        for xml path('')), 1, 2, '')
    from (
        select distinct station
        from #temp) s; -- distinct stations
    

    结果

    station     client_codes
    ----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    0           B, C, D, E, G, J
    1           A, B, D, G, H, J
    2           A, C, E, F, G, H, J
    3           B, C, H, J
    4           A, B, C, D, F, H, J
    5           H, J
    6           D, E, F, G, I
    7           A, C, D, F, G, H, J
    8           A, E, G
    9           C, E, F, G, I
    

    希望这有帮助。