SQL Server:内部联接和分组依据

时间:2012-07-27 09:21:24

标签: sql-server tsql

我有一个查询计算每天电话接线员的查询次数

SELECT 
   [OperatorID],
   DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate,
   COUNT(*) AS EnquiryCount
FROM 
   [Enquiries] AS e
GROUP BY 
   [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0)

但是,我想将Operator表添加到此查询中,以便我可以检索运算符名称

SELECT [OperatorID]
  ,[FirstName]
  ,[LastName]
FROM [Operators]

如果我在group by子句之前连接2个表:

SELECT [OperatorID]
  , DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate
  , COUNT(*) AS EnquiryCount
  , st.FullName
FROM [Enquiries] AS e

INNER JOIN

(SELECT     OperatorID, FirstName + ' ' + LastName AS FullName 
FROM          dbo.Operators
WHERE      (Role = 'Operator')) AS o ON e.OperatorID = o.OperatorID

GROUP BY [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0)

我收到以下错误:

  

列'o.FullName'在选择列表中无效,因为它不是   包含在聚合函数或GROUP BY子句中。

我该如何解决这个问题?

5 个答案:

答案 0 :(得分:2)

由于OperatorIDFullName更有特色,您可以安全地将FullName添加到group by子句中:

SELECT [OperatorID]
  , DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate
  , COUNT(*) AS EnquiryCount
  , st.FullName
FROM [Enquiries] AS e

INNER JOIN

(SELECT     OperatorID, FirstName + ' ' + LastName AS FullName 
FROM          dbo.Operators
WHERE      (Role = 'Operator')) AS o ON e.OperatorID = o.OperatorID

GROUP BY [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0), st.FullName

UPDATE 正如评论中所述,我建议首先按最小所需的列数进行聚合,然后装饰结果。

SELECT si.[OperatorID], si.CreationDate, si.EnquiryCount, st.FullName
FROM

(
    SELECT [OperatorID]
      , DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate
      , COUNT(*) AS EnquiryCount
    FROM [Enquiries]
    GROUP BY [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0)
) AS si

INNER JOIN

(
    SELECT     OperatorID, FirstName + ' ' + LastName AS FullName 
    FROM          dbo.Operators
    WHERE      (Role = 'Operator')
) AS st

   ON si.OperatorID = st.OperatorID

实际上我不确定,为什么你需要子查询Operators。如果没有必要,那么解决方案可以简化:

SELECT si.[OperatorID], si.CreationDate, si.EnquiryCount,
    st.FirstName + ' ' + st.LastName AS FullName
FROM

(
    SELECT [OperatorID]
      , DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate
      , COUNT(*) AS EnquiryCount
    FROM [Enquiries]
    GROUP BY [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0)
) AS si

INNER JOIN

Operators AS st
  ON si.OperatorID = st.OperatorID and st.Role = 'Operator'

答案 1 :(得分:1)

请试试,我还没有测试过!希望这能解决错误

SELECT [OperatorID], CONCAT(FirstName,LastName) AS FullName , DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate , COUNT(*) AS EnquiryCount , st.FullName FROM [Enquiries] AS e INNER JOIN dbo.Operators ON dbo.Operators.OperatorID = e.OperatorID AND (Role = 'Operator') GROUP BY [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0)

答案 2 :(得分:0)

只需将st.FullName添加到Group by

即可
GROUP BY 
   [OperatorID], 
   DATEADD(day, DATEDIFF(day, 0, CreationDate), 0), 
   st.FullName

答案 3 :(得分:0)

您可以使用包含ROW_NUMBER函数和COUNT(*)OVER的公用表表达式:

WITH cte AS
(
   SELECT e.[OperatorID]
  , DATEADD(day, DATEDIFF(day, 0, e.CreationDate), 0) AS CreationDate
  , o.FirstName + ' ' + o.LastName AS FullName 
  , RN = ROW_NUMBER()OVER(PARTITION BY [o.OperatorID], DATEADD(day, DATEDIFF(day, 0, e.CreationDate), 0) ORDER BY e.CreationDate DESC)
  , EnquiryCount = COUNT(*)OVER(PARTITION BY [o.OperatorID], DATEADD(day, DATEDIFF(day, 0, e.CreationDate), 0))
   FROM [Enquiries] AS e
   INNER JOIN  dbo.Operators o ON e.OperatorID = o.OperatorID
   WHERE Role = 'Operator'
)
SELECT * FROM cte
WHERE RN = 1

答案 4 :(得分:0)

使用公用表表达式可以

with cte as (
SELECT  
   [OperatorID], 
   DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) AS CreationDate, 
   COUNT(*) AS EnquiryCount 
FROM  
   [Enquiries] AS e 
GROUP BY  
   [OperatorID], DATEADD(day, DATEDIFF(day, 0, CreationDate), 0) 
)
SELECT
 cte.OperatorI,cte.CreationDate,o.FirstName + ' ' + o.LastName AS FullName   
FROM
 cte inner join dbo.Operators o
 on o.Role = 'Operator' and e.OperatorID = o.OperatorID