Добавление процентов к нескольким подсчетам в одном запросе SQL SELECT - PullRequest
3 голосов
/ 20 августа 2009

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

SELECT  invalidCount = (SELECT COUNT(*) FROM <...a...> WHERE <...b...>),
        unknownCount = (SELECT COUNT(*) FROM <...c...> WHERE <...d...>),
        totalCount   = (SELECT COUNT(*) FROM <...e...> WHERE <...f...>)

Это работает нормально, но я хотел добавить два процента столбцов в SELECT:

invalidCount * 100 / totalCount AS PercentageInvalid, 
unknownCount * 100 / totalCount AS UnknownPercentage

Как мне изменить мой оператор SELECT, чтобы справиться с этим?

Ответы [ 5 ]

4 голосов
/ 20 августа 2009

Вы можете использовать подзапрос в предложении from:

select
    s.invalidCount,
    s.unknownCount,
    s.totalCount,
    invalidCount * 100 / s.totalCount as PercentageInvalid,
    unknownCount * 100 / s.totalCount as PercentageUnknown
from
    (select  invalidCount = (SELECT COUNT(*) FROM <...a...> WHERE <...b...>),
        unknownCount = (SELECT COUNT(*) FROM <...c...> WHERE <...d...>),
        totalCount       = (SELECT COUNT(*) FROM <...e...> WHERE <...f...>)) s
3 голосов
/ 20 августа 2009
SELECT invalidCount, 
  unknownCount, 
  totalCount, 
  invalidCount * 100 / totalCount AS PercentageInvalid, 
  unknownCount * 100 / totalCount AS UnknownPercentage 
FROM 
    (
      SELECT  invalidCount = (SELECT COUNT(*) FROM <...a...> WHERE <...b...>),  
      unknownCount = (SELECT COUNT(*) FROM <...c...> WHERE <...d...>),     
      totalCount       = (SELECT COUNT(*) FROM <...e...> WHERE <...f...>)
    )
1 голос
/ 05 октября 2009

Я бы определенно согласился с решением Майка! Гораздо элегантнее и эффективнее.

Но я не вижу причин, чтобы не использовать GROUP BY здесь. Это сделало бы его еще более элегантным и эффективным. Я бы предложил избавиться от лишнего «COUNT (*) OVER (PARTITION BY 1)» и вместо этого суммировать счет.

SELECT CardType 
       , COUNT(*) AS TypeCount
       , SUM(COUNT(*)) OVER () AS TotalCount
       , COUNT(*) * 1.0 / SUM(COUNT(*)) OVER () AS TypePercent
FROM Sales.CreditCard
GROUP BY CardType

Примечания:

  • "PARTITION BY 1" был избыточен, поэтому пропущен.
  • Принимая СУММУ CardType-Counts экономит нам от подсчета всей таблицы один раз снова без разбиения.
  • * 1,0 используется вместо приведения.
  • Запрос не проверен, но он должен работать ..
1 голос
/ 20 августа 2009

Вот другой подход, использующий предложение OVER, которое очень круто - очень эффективно. Посмотрите этот пример на AdventureWorks:

SELECT DISTINCT CardType 
        ,COUNT(*) OVER (PARTITION BY CardType) AS TypeCount
        ,COUNT(*) OVER (PARTITION BY 1) AS TotalCount
        ,COUNT(*) OVER (PARTITION BY CardType) / CAST(COUNT(*) OVER (PARTITION BY 1) AS float) AS TypePercent
FROM Sales.CreditCard
0 голосов
/ 20 августа 2009
SELECT  invalidCount = (SELECT COUNT(*) FROM <...a...> WHERE <...b...>),
        unknownCount = (SELECT COUNT(*) FROM <...c...> WHERE <...d...>),
        totalCount       = (SELECT COUNT(*) FROM <...e...> WHERE <...f...>)
INTO #tmp

SELECT invalidCount,
       unknownCount,
       totalCount,
       invalidCount * 100 / totalCount AS PercentageInvalid, 
       unknownCount * 100 / totalCount AS UnknownPercentage
FROM #tmp

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