2012-07-27 45 views
1

我有一个统计由电话运营商,每天处理的查询数查询SQL服务器:内部连接和组由

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] 

如果我内心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) 

我收到以下错误:

Column 'o.FullName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

如何解决此问题?

回答

0

只需添加st.FullNameGroup by

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

谢谢马格努斯。惊人的快速反应。欢呼声 – BrightonDev 2012-07-27 09:32:45

+0

我会接受这个,因为它回答了这个问题。感谢所有其他建议。 – BrightonDev 2012-07-27 16:05:21

2

由于OperatorIDFullName比较有特色的比你可以安全地通过子句添加FullName到组:

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' 
+0

并且从长远来看,我建议将FullName作为连接添加到已经聚合的数据中,因为通过OperatorID + FullName进行分组要快得多。如果你感兴趣,请告诉我。 – 2012-07-27 09:26:40

+0

谢谢库巴,是的,我想看一个你的意思的例子。 – BrightonDev 2012-07-27 09:31:57

+0

感谢您的建议库巴 – BrightonDev 2012-07-27 16:06:24

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)

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 
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