2011-02-04 2 views
0

Я хочу создать запрос, который показывает имя сотрудника и сумму всей не закрытой службы. Результат запроса не дает мне правильного значения.Проблема с подсчетом в запросе SQL

Вот мой запрос:

SELECT DISTINCT 
     a.AssignedEmp, 
     COUNT(a.TipoStatus) AS 'Service Request Count' 
    FROM Service a, 
     employee b 
    WHERE b.Classification_ClassificationID = 2 
    AND a.TipoStatus = 'Open' 
    OR a.TipoStatus = 'Pending' 
    OR a.TipoStatus = 'Hold' 
    OR a.TipoStatus = 'Warranty' 
    AND a.AssignedEmp = b.UserName 
GROUP BY a.AssignedEmp 
    LIMIT 0, 30 

Там результат, что этот запрос дает мне это:

dpadil 16 
epadil  8 

Правильные значения должны быть 2 и 1.

+0

Это для MySQL, SQLite или PostgreSQL? –

+1

@OMG, вы знаете, что есть _other_ СУБД? :-) – paxdiablo

+2

@paxdiablo: Только три, которые я знаю, поддерживают «LIMIT». И не называйте меня «Ширли»: p –

ответ

2

Вы должны скобки вокруг условий OR-нут (и должны использовать JOIN обозначения):

SELECT DISTINCT 
     a.AssignedEmp, 
     COUNT(a.TipoStatus) AS 'Service Request Count' 
    FROM Service AS a 
    JOIN employee AS b ON a.AssignedEmp = b.UserName 
WHERE b.Classification_ClassificationID = 2 
    AND (a.TipoStatus = 'Open' 
    OR a.TipoStatus = 'Pending' 
    OR a.TipoStatus = 'Hold' 
    OR a.TipoStatus = 'Warranty') 
GROUP BY a.AssignedEmp 
LIMIT 0, 30 

Или вы можете записать условие непосредственно в терминах 'не закрыто':

SELECT DISTINCT 
     a.AssignedEmp, 
     COUNT(a.TipoStatus) AS 'Service Request Count' 
    FROM Service AS a 
    JOIN employee AS b ON a.AssignedEmp = b.UserName 
WHERE b.Classification_ClassificationID = 2 
    AND a.TipoStatus != 'Closed' 
GROUP BY a.AssignedEmp 
LIMIT 0, 30 

Как первоначально написано, предложение WHERE было эквивалентно:

WHERE (b.Classification_ClassificationID = 2 AND a.TipoStatus = 'Open') 
    OR a.TipoStatus = 'Pending' 
    OR a.TipoStatus = 'Hold' 
    OR (a.TipoStatus = 'Warranty' AND a.AssignedEmp = b.UserName) 

Подсчитывает все элементы Open, имеющие идентификатор классификации 2 для пользователя; он также учитывает все ожидающие пункты обслуживания независимо от идентификатора классификации и всех элементов обслуживания «Удержание» независимо от идентификатора классификации и всех пунктов обслуживания гарантии, назначенных пользователю, независимо от идентификатора классификации. GROUP BY фильтрует вещи так, чтобы учитывались только элементы с нужным назначенным сотрудником, но для некоторых терминов есть частичный кросс-продукт, приводящий к раздутым подсчетам.

+0

Это работает отлично! Спасибо Джонатан и всем, кто помогает! – maltad

3

первый вещь, которую вы должны сделать, это избавиться от count и group by.

Это даст вам реальные ряды, которые используются и, вероятно, покажут вам проблему прямо.

Тот факт, что отношения верны (16:8 = 2:1), обычно указывает, что AND a.AssignedEmp = b.UserName не является таким ограничивающим, как вы думаете.

Другими словами, соединения в перекрестном столе более плодовиты. Получение самих строк поможет вам понять, почему.

0

Возможно, вы захотите структурировать свое состояние более явно.

Вы также должны указать условие JOIN, используя оператор JOIN, а не дополнительное условие.

SELECT DISTINCT   
a.AssignedEmp,   
COUNT(a.TipoStatus) AS 'Service Request Count'  
FROM Service a 
     INNER JOIN employee b 
     ON a.AssignedEmp = b.UserName 
WHERE b.Classification_ClassificationID = 2  
    AND (
     a.TipoStatus = 'Open'  
     OR a.TipoStatus = 'Pending'  
     OR a.TipoStatus = 'Hold'  
     OR a.TipoStatus = 'Warranty' 
     ) 
GROUP BY a.AssignedEmp  
    LIMIT 0, 30 
Смежные вопросы