SQL Server:像行一样组合

时间:2014-06-06 17:25:58

标签: sql sql-server sql-server-2008 group-by inner-join

我有以下查询:

SELECT DISTINCT [WL].[Id]
  ,[WL].[UserId]
  ,[WL].[DIF]
  ,[WL].[MW]
  ,[WL].[Notes]
  ,[WL].[WDate]
  ,[WL].[CB]
  ,[WL].[MPH] 
  ,[U].[Id]
  ,[U].[UserName]
  ,[U].[We]
  ,[U].[SLength]
  ,[U].[UP]
  ,[U].[PU]
  ,[U].[ANumber]
  ,[U].[G_CK]
FROM 
    [Wsite].[dbo].[WLog] as WL 
INNER JOIN 
    [Wsite].[dbo].[Users] AS U ON [U].[Id] = [WL].[UserId] 
WHERE 
    [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
    AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)
GROUP BY 
    [WL].[UserId]

我得到的错误是:

  

专栏&#39; Wsite.dbo.WLog.Id&#39;在选择中无效   list,因为它不包含在聚合函数中   GROUP BY子句。

如果列表中有多个UserID,我想要的是组合数据。

举个例子:

Id  | UserId | .... | Id   | UserName    | SLength | ....
5843| 99304  | .... | 99304| Bob Barker  | 14      | ....
5844| 06300  | .... | 06300| Dean Martin | 104     | ....
5845| 99304  | .... | 99304| Bob Barker  | 8       | ....
5846| 99304  | .... | 99304| Bob Barker  | 11      | ....
5847| 7699   | .... | 7699 | John Doe    | 0       | ....

所以看起来应该是这样的:

Id  | UserId | .... | Id   | UserName    | SLength | ....
5843| 99304  | .... | 99304| Bob Barker  | 33      | ....
5844| 06300  | .... | 06300| Dean Martin | 104     | ....
5847| 7699   | .... | 7699 | John Doe    | 0       | ....

请注意 Bob Barker SLength 合并(14 + 8 + 11 = 33)。

任何帮助都会很棒!谢谢!

更新

SELECT DISTINCT 
   MIN([WL].[Id]) AS [WLID]
  ,MIN([WL].[UserId]) AS [WLUD]
  ,SUM([WL].[DIF]) AS [DIF]
  ,SUM([WL].[MW]) AS [MW]
  ,[WL].[Notes]
  ,[WL].[WDate]
  ,SUM([WL].[CB]) AS [CB]
  ,SUM([WL].[MPH])  AS [MPH]
  ,MIN([U].[Id] AS [UID]
  ,MIN([U].[UserName] AS [UUserName]
  ,[U].[We]
  ,SUM([U].[SL]) AS [SL]
  ,[U].[UP]
  ,[U].[PU]
  ,[U].[ANumber]
  ,[U].[G_CK]
  FROM [Wsite].[dbo].WLog as WL 
INNER JOIN [Wsite].[dbo].[Users] AS U 
    ON [U].[Id] = [WL].[UserId] 
 WHERE [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
   AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)
GROUP BY 
   [WL].[Notes]
  ,[WL].[WDate]
  ,[U].[We]
  ,[U].[UP]
  ,[U].[PU]
  ,[U].[ANumber]
  ,[U].[G_CK]
ORDER BY [U].[UserName] DESC

4 个答案:

答案 0 :(得分:1)

当您使用GROUP BY时,表示您希望将相似的元素组合在一起,并显示您要显示的其余项目的某种聚合(COUNT,SUM,MIN等)。 Becaus这样做,如果在选择列表中包含[WL]。[Id],你基本上可以得到完整的选择而不进行任何聚合(因为[WL]。[Id]是唯一的。)

您需要执行以下操作:

SELECT MIN([WL].[Id]) AS ID
  ,[WL].[UserId]
  ,[U].[Id]
  ,[U].[UserName]
  ,SUM([SLength]) AS SLength
FROM [Wsite].[dbo].[WLog] as WL 
INNER JOIN [Wsite].[dbo].[Users] AS U 
        ON [U].[Id] = [WL].[UserId] 
     WHERE [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
       AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)
  GROUP BY [WL].[UserId]
  ,[U].[Id]
  ,[U].[UserName]

(为简洁起见,我没有包括所有字段。)

另请注意,由于[WL]。[Id]似乎是唯一的,因此在此上下文中没有任何意义,除非您想要显示其第一次出现(然后您可以添加MIN([WL]。[Id]) SELECT列表)。

答案 1 :(得分:0)

如果您使用GROUP BY,则必须以某种方式汇总不在分组中的所有列(SUMMINMAX等)

试试这个:

SELECT 
   [WL].[Id]
  ,[WL].[UserId]
  ,[WL].[DIF]
  ,[WL].[MW]
  ,[WL].[Notes]
  ,[WL].[WDate]
  ,[WL].[CB]
  ,[WL].[MPH] 
  ,Sum ([U].[SLength]) SLength
FROM [Wsite].[dbo].[WLog] as WL 
INNER JOIN [Wsite].[dbo].[Users] AS U 
    ON [U].[Id] = [WL].[UserId] 
WHERE [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
    AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)
GROUP BY 
   [WL].[Id]
  ,[WL].[UserId]
  ,[WL].[DIF]
  ,[WL].[MW]
  ,[WL].[Notes]
  ,[WL].[WDate]
  ,[WL].[CB]
  ,[WL].[MPH] 

以下是您可以使用的聚合函数:

http://msdn.microsoft.com/en-us/library/ms173454.aspx

答案 2 :(得分:0)

不确定,但这可能适用于您的情况。

SELECT DISTINCT [WL].[Id]
  ,[WL].[UserId]
  ,[WL].[DIF]
  ,[WL].[MW]
  ,[WL].[Notes]
  ,[WL].[WDate]
  ,[WL].[CB]
  ,[WL].[MPH] 
  ,[U].[Id]
  ,[U].[UserName]
  ,[U].[We]
  ,SUM([U].[SLength]) OVER (PARTITION BY [WL].[UserId])
  ,[U].[UP]
  ,[U].[PU]
  ,[U].[ANumber]
  ,[U].[G_CK]
          FROM [Wsite].[dbo].[WLog] as WL 
    INNER JOIN [Wsite].[dbo].[Users] AS U 
            ON [U].[Id] = [WL].[UserId] 
         WHERE [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
           AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)

答案 3 :(得分:-1)

您对GROUP BY的使用不正确。 SELECT中使用的所有列都应该在GROUP BY子句中,或者应该是聚合函数。
您的查询应如下所示。

SELECT DISTINCT MIN([WL].[Id]) [Id]
    ,[WL].[UserId]
    ,[WL].[DIF]
    ,[WL].[MW]
    ,[WL].[Notes]
    ,[WL].[WDate]
    ,[WL].[CB]
    ,[WL].[MPH] 
    ,[U].[Id]
    ,[U].[UserName]
    ,[U].[We]
    ,SUM([U].[SLength]) SLength
    ,[U].[UP]
    ,[U].[PU]
    ,[U].[ANumber]
    ,[U].[G_CK]
FROM [Wsite].[dbo].[WLog] as WL 
    INNER JOIN [Wsite].[dbo].[Users] AS U 
        ON [U].[Id] = [WL].[UserId] 
WHERE [WL].[WDate] >= CONVERT(datetime, '2012-01-01 00:00:00', 120)  
       AND [WL].[WDate] <= CONVERT(datetime, GETDATE(), 120)
GROUP BY [WL].[UserId]
    ,[WL].[DIF]
    ,[WL].[MW]
    ,[WL].[Notes]
    ,[WL].[WDate]
    ,[WL].[CB]
    ,[WL].[MPH] 
    ,[U].[Id]
    ,[U].[UserName]
    ,[U].[We]
    ,[U].[UP]
    ,[U].[PU]
    ,[U].[ANumber]
    ,[U].[G_CK]