2013-07-23 2 views
0

2 У меня есть две таблицыMySQL Query (группа по)

один logs.emails:

EmailNum EmployeeID, Emailcontent, EmailReceivers ,is_read 
    1   1  , "sasa"  , "[email protected]" ,1 
    2   1  , "sasa"  , "[email protected]" ,0 
    3   2  , "sasa"  , "[email protected]" ,0 
    4   2  , "sasa"  , "[email protected]" ,0 
    5   2  , "sasa"  , "[email protected]" ,0 

и Employees.user

id, FirstName, LastNAme 
1 , "John" , "Brown" 
2 , "Jack" , "James" 

Мой желаемого выхода:

FirstName, LastName, NumOfUnreadEmails
Джон Браун, 1
Джек, Джеймс, 3

Моя попытка (Но это не возвращает IRST ряд желаемых результатов, который является "Джон Браун, 1"):

SELECT 
    *, count(EmployeeID) as NumEmails 
FROM 
    logs.emails a 
inner join 
    Employees.user b on a.EmployeeID=b.id 
group by 
    EmployeeID 
having 
    a.is_read='0' 

Ваша помощь ценится

+0

Должен ли Джек Джеймс иметь идентификатор 2 выше? У них обоих одинаковый идентификатор. –

+0

YEs corrected, Thanks –

+0

Вы не можете делать '*, COUNT (' так как вам нужно будет сгруппировать все столбцы. Вы просто хотите * от 'Employees.user'? –

ответ

3

Вы должны указать WHERE, вместо использования HAVING, поскольку вы пытаетесь отфильтровать записи, которые имеют is_read=0, перед тем, как делать какие-либо агрегации.

Кроме того, для того, чтобы получить только нужные поля, не используйте *. Просто укажите нужные поля.

SELECT 
    b.FirstName, b.LastName, COUNT(a.EmailNum) 
FROM 
    logs.emails a 
inner join 
    Employees.user b on a.EmployeeID=b.id 
where 
    a.is_read='0' 
group by 
    b.id 
+2

Это не возвращает сотрудников, у которых нет непрочитанных сообщений электронной почты или вообще нет сообщений электронной почты. Возможно, это нормально, но об этом нужно знать. – GolezTrol

+0

Я не хочу возвращаться либо! –

+0

Это не было упомянуто как требование, но при необходимости вы могли ссылаться на ответ, который вы предоставили, который предоставляет этот результат. –

1

Попробуйте так:

SELECT b.FirstName, b.LastName, 
     sum(case 
       when a.is_read=0 than 1 
       else 0 
      end) as NumOfUnreadEmails 
FROM logs.emails a 
inner join Employees.user b on a.EmployeeID=b.id 
group by b.FirstName, b.LastName 
+0

Это не вернет счет нуля для любого employee.user, у которого нет электронной почты. Существуют способы написать инструкцию, которая вернет нулевое количество, а также (потенциально) улучшить производительность, включив предикат on 'logs.emails.is_read = 0' – spencer7593

1

Это вернет всех сотрудников, в том числе тех, у которых нет никакого электронного письма. Если вы хотите показать только те, у которых есть непрочитанное электронное письмо, вы можете изменить LEFT JOIN на INNER JOIN.

SELECT 
    u.FirstName, 
    u.LastName, 
    COUNT(e.EmployeeID) AS NumOfUnreadEmails 
FROM 
    Employees.user u 
    LEFT JOIN logs.emails e ON e.EmployeeID = u.id AND e.is_read = 0 
GROUP BY 
    u.id 
+0

Это так близко! Но агрегат действительно должен быть чем-то вроде «COUNT (e.EmployeeID)», поэтому мы получаем нулевое количество для пользователей с нулевыми непрочитанными сообщениями. – spencer7593

+0

@ spencer7593 Вы очень правы. Спасибо, сэр, я исправил это. – GolezTrol

+0

+1. Да, это билет. Можно отметить, что «индекс покрытия», например, 'ON logs.emails (EmployeeID, is_read)' может значительно повысить производительность запроса. (И теперь простое удаление ключевого слова LEFT устранит строки с нулевым подсчетом.) – spencer7593

Смежные вопросы