2012-07-27 5 views
1

У меня есть запрос, который подсчитывает количество запросов, сделанных оператором телефона в деньSQL Server: внутренние соединения и группы по

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] 

Если я внутреннее соединение с 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.FullName к Group by:

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

Спасибо Магнус. Удивительно быстрый ответ. Приветствия – BrightonDev

+0

Я собираюсь принять это, потому что он ответил на вопрос. Тем не менее, благодаря всем остальным предложениям. – BrightonDev

2

Как OperatorID более своеобразны, чем FullName, чем вы можете смело добавить 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 намного быстрее, чем группировка по OperatorID + FullName. если вы заинтересованы - дайте мне знать. –

+0

Спасибо, Куба. Да, я хотел бы посмотреть пример того, что вы имеете в виду. – BrightonDev

+0

Спасибо kuba за ваше предложение – BrightonDev

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 
Смежные вопросы