#sql #subquery #aggregate-functions #percentage
#sql #подзапрос #агрегатные функции #процент
Вопрос:
Я пытаюсь получить процентное количество отклоненных утверждений (total_count / denied_count * 100) для поставщиков с менее чем 100 утверждениями. Я могу получить общее количество и отклоненное количество с помощью отдельных запросов, но у меня возникают проблемы с объединением всего вместе.
SELECT
PROVID,
COUNT(CLAIMID) AS TOTAL_COUNT,
COUNT(CLAIMID) / (SELECT COUNT(CLAIMID) * 100
FROM #TEMPSTAGE
WHERE STATUS = 'DENY') AS DENIED_PERCENTAGE
FROM
#TEMPSTAGE
WHERE
PROVID IN (SELECT DISTINCT PROVID
FROM #TEMPSTAGE
GROUP BY PROVID
HAVING COUNT(CLAIMID) <= 100)
GROUP BY
PROVID
Пример результатов:
ProvID / Total_Count / Denied Percentage
-----------------------------------------
X12345 / 77 / 0
Я получаю нулевой процент отказа для всего, поскольку мой подзапрос в инструкции select не позволяет мне группировать по provid.
Ошибка
В списке выбора может быть указано только одно выражение, если подзапрос не введен с помощью EXISTS.
Каков наилучший способ сделать это??
Ответ №1:
Как и в большинстве языков, если вы выполняете 1 / 2
с целыми числами, результатом будет 0
, потому что для 0.5
нет целого числа. Чтобы получить десятичное число (фиксированная точка с плавающей запятой), вам необходимо преобразовать типы данных.
Как зависит от вашего диалекта SQL (MySQL, SQL Server, Oracle, PostgreSQL и т.д.).
CAST(COUNT(CLAIMID) AS FLOAT)
CAST(COUNT(CLAIMID) AS DECIMAL(10, 4))
COUNT(CLAIMID) * 1.0
etc, etc
Далее, для использования IN
список должен быть в фигурных скобках IN (1, 2, 3)
, но для использования вложенного запроса запрос должен быть в фигурных скобках (SELECT x FROM y)
.
Это означает, что для использования обоих вам нужны две пары фигурных скобок IN ((SELECT x FROM y))
Итак, наименьшие изменения в вашем запросе следующие…
SELECT
PROVID,
COUNT(CLAIMID) AS TOTAL_COUNT,
COUNT(CLAIMID) / (SELECT COUNT(CLAIMID) * 100.0
FROM #TEMPSTAGE
WHERESTATUS = 'DENY') AS DENIED_PERCENTAGE
FROM
#TEMPSTAGE
WHERE
PROVID IN ((SELECT PROVID
FROM #TEMPSTAGE
GROUP BY PROVID
HAVING COUNT(CLAIMID) <= 100))
GROUP BY
PROVID
Тем не менее, подзапрос в предложении where может быть просто перемещен в основной запрос…
SELECT
PROVID,
COUNT(CLAIMID) AS TOTAL_COUNT,
COUNT(CLAIMID) / (SELECT COUNT(CLAIMID) * 100.0
FROM #TEMPSTAGE
WHERE STATUS = 'DENY') AS DENIED_PERCENTAGE
FROM
#TEMPSTAGE
GROUP BY
PROVID
HAVING
COUNT(CLAIMID) <= 100
Кроме того, я удалил DISTINCT
ключевые слова. Если вы используете GROUP BY
так, как вы есть, вам это не нужно.
ОТРЕДАКТИРОВАНО: Следующий комментарий
Вы можете пропустить подзапрос и просто просуммировать количество строк в группе, в которой находится статус 'DENY'
.
Кроме того, процент (x * 100) / y
не x / (y * 100)
равен, поэтому я изменил вычисление на обратное.
SELECT
PROVID,
COUNT(CLAIMID) AS TOTAL_COUNT,
SUM(CASE WHEN STATUS = 'DENY' THEN 1 ELSE 0 END) * 100.0 / COUNT(CLAIMID) AS DENIED_PERCENTAGE
FROM
#TEMPSTAGE
GROUP BY
PROVID
HAVING
COUNT(CLAIMID) <= 100
Комментарии:
1. @GregoryBrauninger Это не было четко указано в вашем вопросе. Ответ добавлен в
2. Ты потрясающий. Большое вам спасибо! Это беспокоило меня.