2011-12-30 2 views
0

Как я могу улучшить SQL-запрос ниже (SQL Server 2008)? Я хочу, чтобы попытаться избежать суб-выбирает, и я использую пару из них для получения результатов, как этотУлучшение запросов подзапроса

StateId  TotalCount  SFRCount  OtherCount 
--------------------------------------------------------- 
AZ    102    50    52 
CA    2931   2750   181 
etc... 

SELECT 
    StateId, 
    COUNT(*) AS TotalCount, 
    (SELECT COUNT(*) AS Expr1 FROM Property AS P2 
     WHERE (PropertyTypeId = 1) AND (StateId = P.StateId)) AS SFRCount, 
    (SELECT COUNT(*) AS Expr1 FROM Property AS P3 
     WHERE (PropertyTypeId <> 1) AND (StateId = P.StateId)) AS OtherCount 
FROM Property AS P 
GROUP BY StateId 
HAVING (COUNT(*) > 99) 
ORDER BY StateId 

ответ

10

Это может работать так же, трудно проверить без данных

SELECT 
     StateId, 
     COUNT(*) AS TotalCount, 
     SUM(CASE WHEN PropertyTypeId = 1 THEN 1 ELSE 0 END) as SFRCount, 
     SUM(CASE WHEN PropertyTypeId <> 1 THEN 1 ELSE 0 END) as OtherCount 
    FROM Property AS P 
    GROUP BY StateId 
    HAVING (COUNT(*) > 99) 
    ORDER BY StateId 
+3

Ваш ответ должен иметь правильный вывод, и по моему опыту 'SUM (CASE ...)' имеет тенденцию быть удивительно быстрым по сравнению с использованием внутренних выборок. – ean5533

+2

Awesome, спасибо! Я отредактировал ваш ответ, чтобы удалить постороннюю запятую после «OtherCount». – Scott

+0

+1, отличный ответ –

0

Ваш альтернативой является единое самосоединение Property с использованием условий WHERE в качестве параметра объединения. Значение OtherCount может быть получено путем вычитания TotalCount - SFRCount в производном запросе.

0

Другой альтернативой было бы использовать функцию PIVOT, как это:

SELECT StateID, [1] + [2] AS TotalCount, [1] AS SFRCount, [2] AS OtherCount 
FROM Property 
PIVOT (COUNT(PropertyTypeID) 
     FOR PropertyTypeID IN ([1],[2]) 
     ) AS pvt 
WHERE [1] + [2] > 99 

Вы должны добавить запись для каждого типа собственности, которая может быть сложной, но это еще одна альтернатива. У Скотта отличный ответ.

0

Если PropertyTypeId не имеет значения null, вы можете сделать это с помощью единственного соединения. Граф быстрее, чем Sum. Но граф плюс присоединяется быстрее, чем Sum. Тестовый пример ниже подражает вашим данным. docSVsys имеет 800 000 строк, и для caseID имеется около 300 уникальных значений. Count plus Присоединиться к этому тестовому примеру немного быстрее, чем Sum. Но если я удалю с (nolock), то Sum будет примерно на 1/4 быстрее. Вам нужно будет проверить свои данные.

select GETDATE() 
    go; 
    select caseID, COUNT(*) as Ttl, 
     SUM(CASE WHEN mimeType = 'message/rfc822' THEN 1 ELSE 0 END) as SFRCount, 
     SUM(CASE WHEN mimeType <> 'message/rfc822' THEN 1 ELSE 0 END) as OtherCount, 
     COUNT(*) - SUM(CASE WHEN mimeType = 'message/rfc822' THEN 1 ELSE 0 END) as OtherCount2 
    from docSVsys with (nolock) 
    group by caseID 
    having COUNT(*) > 1000 
    select GETDATE() 
    go; 
    select docSVsys.caseID, COUNT(*) as Ttl 
    , COUNT(primaryCount.sID) as priCount 
    , COUNT(*) - COUNT(primaryCount.sID) as otherCount 
    from docSVsys with (nolock) 
    left outer join docSVsys as primaryCount with (nolock) 
     on primaryCount.sID = docSVsys.sID 
     and primaryCount.mimeType = 'message/rfc822' 
    group by docSVsys.caseID 
    having COUNT(*) > 1000 
    select GETDATE() 
    go; 
Смежные вопросы