Подвыбрать Улучшение запроса - PullRequest
0 голосов
/ 30 декабря 2011

Как улучшить приведенный ниже 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

Ответы [ 4 ]

10 голосов
/ 30 декабря 2011

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

    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
0 голосов
/ 30 декабря 2011

Если PropertyTypeId не равен NULL, вы можете сделать это с помощью одного соединения.Счет быстрее чем сумма.Но граф плюс присоединиться быстрее, чем сумма.Тестовый пример ниже имитирует ваши данные.В docSVsys содержится 800 000 строк, а для caseID есть около 300 уникальных значений.Подсчет плюс присоединение в этом тестовом случае немного быстрее, чем сумма.Но если я удалю с (nolock), то сумма будет примерно на 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;
0 голосов
/ 30 декабря 2011

Другой альтернативой может быть использование функции 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 голосов
/ 30 декабря 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...