2009-02-04 3 views
0

Я создаю запрос MySQL, чтобы определить, сколько элементов из каждой из нескольких категорий отображается в заданном диапазоне дат. Моя первая попытка выглядела так:Подзапросы refactor с использованием GROUP BY/HAVING?

select Title, 
    (select count(*) from entries where CategoryID=1 
    and Date >= @StartDate and Date <= @EndDate) as Cat1, 
    (select count(*) from entries where CategoryID=2 
    and Date >= @StartDate and Date <= @EndDate) as Cat2, 
    (select count(*) from entries where CategoryID is null 
    and Date >= @StartDate and Date <= @EndDate) as UnkownCategory 
from entries 
    where Date >= @StartDate and Date <= @EndDate 

В таблице довольно большой, и я хотел бы, чтобы реорганизовать запрос, чтобы ускорить его, но я не знаю, как - это может быть переписана с использованием GROUP BY/HAVING или есть другой способ, которым я не хватает?

Edit: Пример набора результата - что-то вроде этого:

Title | Category 1 Total | Category 2 Total | Unknown Category Total 
ABC  1     3     0 
DEF  2     7     2 
+0

Можете ли вы предоставить пример результирующего? –

+0

Вы делаете сводный запрос. – Loki

ответ

3
select Title, SUM(CategoryID=1) as Cat1, SUM(categoryID=2) as Cat2, 
SUM(categoryID IS NULL) as UnknownCategory 
FROM entries 
WHERE Date BETWEEN @StartDate AND @EndDate 
GROUP BY Title 

Вы можете вставить выражения в сумме() функции: истина равна 1, ложь равно 0. Кроме того, я использовал между оператором, который немного быстрее.

Альтернатива, которая будет возвращать другой макет результата, но немного концептуально проще:

select Title, CategoryID, count(*) 
from entries 
WHERE Date BETWEEN @StartDate AND @EndDate 
group by Title, CategoryID 
+0

Спасибо, что формат на этом отлично и не потребует изменений в генерации отчетов. Это также кажется довольно быстрым. – palmsey

+0

Да, второе решение - это то, что предложил рих. Я придерживаюсь версии SUM, хотя она достаточно быстрая, так как ее формат легче обрабатывать. Благодаря! – palmsey

0
Select COUNT(*), sTitle, CategoryID FROM entries 
WHERE Date >= @StartDate and Date <= @EndDate 
GROUP BY CategoryID, sTitle 
+0

Лучше добавьте CategoryID в результирующий набор! –

+0

Да. Я отредактировал его сейчас. –

+0

Спасибо! Мне действительно нужен счет за запись, но я думаю, что небольшая модификация работает: Выберите счетчик (*), sTitle, CategoryID FROM записей, где Date> = @StartDate и Date <= @EndDate GROUP BY CategoryID, sTitle – palmsey

0

Как о группировке по категориям ид затем с помощью имеющего заявление, чтобы отфильтровать определенные категории, как:

select CategoryID, count(*) 
from entries 
where Date >= @StartDate AND Date <= @EndDate 
group by CategoryID 
having CategoryID = 1 or CategoryID = 2 or CategoryID is null 

Если существует несколько названий для каждой категории, вы можете группировать оба поля:

select Title, CategoryID, count(*) 
from entries 
where Date >= @StartDate AND Date <= @EndDate 
group by Title, CategoryID 
having CategoryID = 1 or CategoryID = 2 or CategoryID is null 
+0

Поместите categoryID в предложении where, а не в отношении предложения. – jmucchiello