В настоящее время я работаю с набором данных о столкновениях, который содержит все случаи, произошедшие в данный день. Моим первым побуждением было получить итоги за данный день, где вывод выглядел примерно так:
Приведенный выше пример является результатом следующего запроса:
SELECT collision_date, SUM(severe_injury_count),SUM(injured_victims)
FROM collisions c
GROUP BY collision_date
LIMIT 50,100;
Я хотел рассчитать процентное отношение числа тяжелых_травм/пострадавших_жертв, я думал, что это будет просто, поэтому я попытался запустить этот запрос (с несколькими вариантами того, как я мог вычислить % - как только я заметил, что это не дает мне того, что я намеревался):
SELECT
collision_date,
SUM(severe_injury_count/injured_victims) AS chance_being_sever_injured,
SUM(severe_injury_count),
SUM(injured_victims),
(severe_injury_count/injured_victims)*100,
(SUM(severe_injury_count)/SUM(injured_victims))*100
FROM collisions c
GROUP BY collision_date;
Но результат, который мне дали, действительно выполняет расчет, как я и ожидал, давая мне такие результаты, как:
Я проверил типы переменных, и все они являются целыми числами, а не строками, поэтому я ожидал, что будут рассчитаны фактические проценты.
Учитывая выходные результаты, я считаю, что мне не хватает чего-то фундаментального при выполнении операций такого типа.
Я также пытался использовать FORMAT(), но вывод тоже был нулевым...
ФОРМАТ((СУММ(количество_тяжелых_травм)/СУММ(пострадавшие_пострадавшие))*100,2)
Любое понимание будет высоко оценено.
Спасибо за ваше время и отзыв.
Реализация предложений, следовательно, расширение исходного сообщения:
Я также пробовал следующее:
SELECT collision_date, SUM(severe_injury_count),SUM(injured_victims),CAST(SUM(severe_injury_count)/SUM(injured_victims) AS DECIMAL)
FROM collisions c
GROUP BY collision_date
LIMIT 50,100;
Пытался также исключить возможные NULL:
SELECT collision_date, SUM(severe_injury_count),SUM(injured_victims),CAST(SUM(severe_injury_count)/SUM(injured_victims) AS DECIMAL)
FROM collisions c WHERE severe_injury_count IS NOT NULL OR injured_victims IS NOT NULL
GROUP BY collision_date
LIMIT 50,100;
SELECT collision_date, SUM(severe_injury_count),SUM(injured_victims),CAST(SUM(severe_injury_count)/SUM(injured_victims) AS DECIMAL)
FROM collisions c WHERE severe_injury_count > 0 OR injured_victims > 0
GROUP BY collision_date
LIMIT 50,100;
Все приведенные выше альтернативы дают мне 0 в качестве значений для столбца «процент», который я пытаюсь вычислить.
Также предпринята попытка принудить тип для данного столбца, как это было предложено @easleyfixed, следующим образом:
SELECT collision_date, SUM(severe_injury_count),SUM(injured_victims),CAST(SUM(CAST(severe_injury_count AS INT))/SUM(CAST(injured_victims AS INT)) AS DECIMAL)
FROM collisions c WHERE severe_injury_count > 0 OR injured_victims > 0
GROUP BY collision_date;
Расширение предложений @nnichols и @easleyfixed
Чтобы лучше проиллюстрировать данные, выполните:
SELECT collision_date,COUNT(*)
FROM collisions c
GROUP BY collision_date;
Дает мне (представляет количество записей для данной даты):
Поэтому я расширил запрос, чтобы попытаться включить то, что я пытаюсь оценить.
SELECT collision_date,COUNT(*),SUM(severe_injury_count),SUM(injured_victims),
SUM(severe_injury_count)/SUM(injured_victims) AS chance_being_sever_injured
FROM collisions c
GROUP BY collision_date;
Выходы:
Я дважды проверил типы баз данных, а те, у которых есть столбцы, - INT, но на самом деле столкновение_дата установлено как «ТЕКСТ».
Для Sh * t и хихиканья я сделал:
SELECT CAST(collision_date AS DATE),COUNT(*),SUM(severe_injury_count),SUM(injured_victims),
SUM(severe_injury_count)/SUM(injured_victims) AS chance_being_sever_injured
FROM collisions c
GROUP BY collision_date;
Также попытка принудить NULL к 0, как это также предлагалось.
SELECT collision_date ,COUNT(*),SUM(IFNULL(severe_injury_count,0)),SUM(IFNULL(injured_victims,0)),
SUM(IFNULL(severe_injury_count,0))/SUM(IFNULL(injured_victims,0)) AS chance_being_sever_injured
FROM collisions c
GROUP BY collision_date;
Выходы:
Я действительно сбит с толку...
@easleyfixed - спасибо за ответ. Я пробовал: "CAST((СУММ(количество_тяжелых_травм)/СУММ(пострадавшие_жертвы))*100 AS float)", а также "CAST((СУММ(количество_тяжелых_травм)/СУММ(пострадавшие_жертв))*100 КАК ДЕСЯТИЧНОЕ число)", но вывод равен 0 для обоих случаев.
Я вижу некоторые значения NULL
в результатах, и это не числовые значения...
Это странно, поскольку NULL не является числовым, как вы сказали. Эта ссылка дает вам какое-либо представление? database.guide/format-a-number-as-a-percentage-in-mysql/….
@easleyfixed спасибо за ссылку, но это не то, что я ищу .... Меня не беспокоит вывод столбца со знаком «%», я пытаюсь понять, почему это не так. t вычисления не выполняются, а также пытаются выяснить, как правильно выполнить такую операцию при выполнении запроса. Набор данных можно найти здесь: kaggle.com/datasets/alexgude/…
@Luuk да, я считаю, что это «коренная» причина, но моя проблема заключается в том, чтобы выяснить, откуда берется этот «NULL» ... Возьмите первую строку второго «вывода», 2001-02-20 - столбец: шанс_быть_sever_injured дает 13, что не имеет смысла. СУММ(количество_тяжелых_травм) и СУММ(раненые_жертвы) имеют значения 19/785 соответственно. Таким образом, для последнего столбца второго вывода я ожидал, что SUM(тяжелые_травмы_количество)/СУММ(раненные_жертвы))*100 будет (19/785)*100 = 2,42, и я получу NULL, если сделаю "(тяжелые_травмы_количество/травмированные_жертвы )*100", что я сделал, например. только для проверки, я знаю, что это неправильно
Хорошо, еще одна вещь, которую вы пытаетесь преобразовать, - это преобразовать типы данных при использовании, например, в случае, когда мы предполагаем, что числа будут целыми числами (например, 200 человек в день), поэтому приведите это число как INT, прежде чем использовать его, ДАЖЕ, если оно уже INT, и смысл этого, по крайней мере, в случае NULLS, теперь они будут отображаться как 0. Не решение, как говорится, но, возможно, двигает нас в правильном направлении, чтобы выяснить, почему существуют нули.
Вы пытались просмотреть строки, используя ISNULL (столбец), и просто посмотреть, где и сколько их есть, чтобы увидеть, можете ли вы выяснить источник нулевого значения или если в базе данных нет ни одного, и это только дает вам null в результате вашей формулы.
Какую СУБД и версию вы используете? Вы не можете CAST
to INT
в MySQL. Вы не ответили на мой предыдущий вопрос о нескольких экземплярах одной и той же даты, когда это столбец, по которому вы группируете.
@nnichols извините за задержку. Я использую SQLite, развернутый в СУБД DBeaver. Вы правы, многократное 2001-02-20
было упущением из-за того, что я пытался представить результат. Типы базы данных столбцов sever_injury_count и inured_victim — INT. Пожалуйста, обратитесь к дополнительным комментариям, которые я добавил к тексту сообщения.
MySQL и SQLite определенно не одно и то же! Я обновил тег на ваш вопрос.
Целочисленное деление дает целочисленный результат, усеченный до нуля. документы
Вам нужно привести к REAL
или FLOAT
, чтобы деление работало на SQLite:
SELECT
collision_date,
SUM(severe_injury_count),
SUM(injured_victims),
ROUND(CAST(SUM(severe_injury_count) AS REAL) / CAST(SUM(injured_victims) AS REAL) * 100, 2)
FROM collisions
GROUP BY collision_date
NULLS, наблюдаемые в одном из ваших тестов, были результатом деления на 0 (ноль).
это помогло, я не знал, что SQLite не ведет себя как MySQL. Спасибо за отзыв и помощь.
Попробуйте CAST как DECIMAL или, возможно, FLOAT в зависимости от.