Эффективный способ расчета процента с условиями - PullRequest
0 голосов
/ 28 мая 2018

У меня есть примерный набор данных, как показано ниже:

TOPIC     STATUS
Physics     C
Maths       I
Chemistry   C
Chemistry   I
Chemistry   I
Maths       C
Maths       C
Physics     I
Physics     C
Maths       C

Как получить процент от TOPIC, который завершается от общего количества попыток, как показано ниже?

Формулы для процентов - это 100 * (общее число C / общее количество вхождений)

TOPIC     PERCENT
Physics     66.66
Maths       75
Chemistry   33.33

Обычно я пишу подзапросы вполучить это, если в T-SQL (я уже знаком с).
Тем не менее, я новичок в postgreSQL, и прежде чем писать те же подзапросы, я просто хотел проверить, существует ли эффективный способ получить это в postgreSQL.

Обновление по запросу
Я получаю ожидаемый результат с приведенным ниже кодом T-SQL, но ищу эффективный способ использования psql

IF OBJECT_ID('tempDB..##SOO',N'U') IS NOT NULL
DROP TABLE ##SOO
GO
SELECT * INTO ##SOO FROM(
SELECT 'PHYSICS' [TOPIC],'C' [STATUS]
UNION ALL
SELECT 'PHYSICS' [TOPIC],'C' [STATUS]
UNION ALL
SELECT 'PHYSICS' [TOPIC],'I' [STATUS]
UNION ALL
SELECT 'MATHS' [TOPIC],'C' [STATUS]
UNION ALL
SELECT 'MATHS' [TOPIC],'C' [STATUS]
UNION ALL
SELECT 'MATHS' [TOPIC],'I' [STATUS]
UNION ALL
SELECT 'MATHS' [TOPIC],'C' [STATUS]
UNION ALL
SELECT 'CHEMISTRY' [TOPIC],'I' [STATUS]
UNION ALL
SELECT 'CHEMISTRY' [TOPIC],'I' [STATUS]
UNION ALL
SELECT 'CHEMISTRY' [TOPIC],'C' [STATUS]
)A

GO

SELECT S.TOPIC, 100*S.PASS/S.KNT [PERCENTO] FROM(
SELECT A.TOPIC,A.KNT,B.PASS FROM(
SELECT TOPIC, COUNT(1) [KNT] FROM ##SOO
GROUP BY TOPIC)A
JOIN 
(SELECT TOPIC, COUNT(1) [PASS] FROM ##SOO
WHERE [STATUS] ='C'
GROUP BY TOPIC)B ON A.TOPIC=B.TOPIC
)S

1 Ответ

0 голосов
/ 28 мая 2018

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

Однако в Postgres (и SQL Server) его действительно можно упростить:

select topic, 
       (count(*) filter (where status = 'C'))::numeric / count(*) as pct
from soo
group by topic;

Обратите внимание, что вышеперечисленное также будет работать в SQL Server, если вы замените предложение filter() выражением case:

select topic, 
       (count(case when status = 'C' then 1 end))::numeric / count(*) as pct
from soo
group by topic;

Онлайн-пример: http://rextester.com/HGTZJ63653

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