Процент и ГРУППА ПО

В настоящее время я работаю с набором данных о столкновениях, который содержит все случаи, произошедшие в данный день. Моим первым побуждением было получить итоги за данный день, где вывод выглядел примерно так:

столкновение_дата СУММ(количество_тяжелых_травм) СУММ(раненые_жертвы) 20 февраля 2001 г. 19 785 20 февраля 2001 г. 12 697 20 февраля 2001 г. 28 823 20 февраля 2001 г. 29 871

Приведенный выше пример является результатом следующего запроса:

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;

Но результат, который мне дали, действительно выполняет расчет, как я и ожидал, давая мне такие результаты, как:

столкновение_дата шанс_быть_север_травмированным СУММ(количество_тяжелых_травм) СУММ(раненые_жертвы) (тяжелые_травмы_количество/раненые_жертвы)*100 (СУММ(количество_тяжелых_травм)/СУММ(раненых_жертв))*100 20 февраля 2001 г. 13 19 785 НУЛЕВОЙ 0 20 февраля 2001 г. 5 12 697 НУЛЕВОЙ 0 20 февраля 2001 г. 17 28 823 0 0 20 февраля 2001 г. 18 29 871 НУЛЕВОЙ 0

Я проверил типы переменных, и все они являются целыми числами, а не строками, поэтому я ожидал, что будут рассчитаны фактические проценты.

Учитывая выходные результаты, я считаю, что мне не хватает чего-то фундаментального при выполнении операций такого типа.

Я также пытался использовать 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;

Дает мне (представляет количество записей для данной даты):

столкновение_дата СЧИТАТЬ(*) 2001-01-01 1000 2001-01-02 1330 03 января 2001 г. 1329 2001-01-04 1346 2001-01-05 1457 и т. д. и т. д.

Поэтому я расширил запрос, чтобы попытаться включить то, что я пытаюсь оценить.

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;

Выходы:

столкновение_дата СЧИТАТЬ(*) СУММ(количество_тяжелых_травм) СУММ(раненые_жертвы) СУММ(количество_тяжелых_травм)/СУММ(раненые_жертвы) КАК шанс_получить_серьезную_травму 2001-01-01 1000 37 676 0 2001-01-02 1330 30 797 0 03 января 2001 г. 1329 28 793 0 2001-01-04 1346 23 758 0 2001-01-05 1457 30 836 0 и т. д. и т. д. и т. д. и т. д. и т. д.

Я дважды проверил типы баз данных, а те, у которых есть столбцы, - 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;
CAST(collision_date AS DATE) СЧИТАТЬ(*) СУММ(количество_тяжелых_травм) СУММ(раненые_жертвы) СУММ(количество_тяжелых_травм)/СУММ(раненые_жертвы) КАК шанс_получить_серьезную_травму 2001 1000 37 676 0 2001 1330 30 797 0 2001 1329 28 793 0 2001 1346 23 758 0 2001 1457 30 836 0 и т. д. и т. д. и т. д. и т. д. и т. д.

Также попытка принудить 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;

Выходы:

столкновение_дата СЧИТАТЬ(*) СУММ(количество_тяжелых_травм) СУММ(раненые_жертвы) СУММ(количество_тяжелых_травм)/СУММ(раненые_жертвы) КАК шанс_получить_серьезную_травму 2001-01-01 1000 37 676 0 2001-01-02 1330 30 797 0 03 января 2001 г. 1329 28 793 0 2001-01-04 1346 23 758 0 2001-01-05 1457 30 836 0 и т. д. и т. д. и т. д. и т. д. и т. д.

Я действительно сбит с толку...

Попробуйте CAST как DECIMAL или, возможно, FLOAT в зависимости от.

easleyfixed 09.02.2023 21:15

@easleyfixed - спасибо за ответ. Я пробовал: "CAST((СУММ(количество_тяжелых_травм)/СУММ(пострадавшие_жертвы))*100 AS float)", а также "CAST((СУММ(количество_тяжелых_травм)/СУММ(пострадавшие_жертв))*100 КАК ДЕСЯТИЧНОЕ число)", но вывод равен 0 для обоих случаев.

Technobrat 09.02.2023 21:21

Я вижу некоторые значения NULL в результатах, и это не числовые значения...

Luuk 09.02.2023 21:26

Это странно, поскольку NULL не является числовым, как вы сказали. Эта ссылка дает вам какое-либо представление? database.guide/format-a-number-as-a-percentage-in-mysql/….

easleyfixed 09.02.2023 21:29

@easleyfixed спасибо за ссылку, но это не то, что я ищу .... Меня не беспокоит вывод столбца со знаком «%», я пытаюсь понять, почему это не так. t вычисления не выполняются, а также пытаются выяснить, как правильно выполнить такую ​​​​операцию при выполнении запроса. Набор данных можно найти здесь: kaggle.com/datasets/alexgude/…

Technobrat 09.02.2023 22:37

@Luuk да, я считаю, что это «коренная» причина, но моя проблема заключается в том, чтобы выяснить, откуда берется этот «NULL» ... Возьмите первую строку второго «вывода», 2001-02-20 - столбец: шанс_быть_sever_injured дает 13, что не имеет смысла. СУММ(количество_тяжелых_травм) и СУММ(раненые_жертвы) имеют значения 19/785 соответственно. Таким образом, для последнего столбца второго вывода я ожидал, что SUM(тяжелые_травмы_количество)/СУММ(раненные_жертвы))*100 будет (19/785)*100 = 2,42, и я получу NULL, если сделаю "(тяжелые_травмы_количество/травмированные_жертвы )*100", что я сделал, например. только для проверки, я знаю, что это неправильно

Technobrat 09.02.2023 22:48

Хорошо, еще одна вещь, которую вы пытаетесь преобразовать, - это преобразовать типы данных при использовании, например, в случае, когда мы предполагаем, что числа будут целыми числами (например, 200 человек в день), поэтому приведите это число как INT, прежде чем использовать его, ДАЖЕ, если оно уже INT, и смысл этого, по крайней мере, в случае NULLS, теперь они будут отображаться как 0. Не решение, как говорится, но, возможно, двигает нас в правильном направлении, чтобы выяснить, почему существуют нули.

easleyfixed 09.02.2023 22:50

Вы пытались просмотреть строки, используя ISNULL (столбец), и просто посмотреть, где и сколько их есть, чтобы увидеть, можете ли вы выяснить источник нулевого значения или если в базе данных нет ни одного, и это только дает вам null в результате вашей формулы.

easleyfixed 09.02.2023 23:14

Какую СУБД и версию вы используете? Вы не можете CAST to INT в MySQL. Вы не ответили на мой предыдущий вопрос о нескольких экземплярах одной и той же даты, когда это столбец, по которому вы группируете.

nnichols 10.02.2023 01:49

@nnichols извините за задержку. Я использую SQLite, развернутый в СУБД DBeaver. Вы правы, многократное 2001-02-20 было упущением из-за того, что я пытался представить результат. Типы базы данных столбцов sever_injury_count и inured_victim — INT. Пожалуйста, обратитесь к дополнительным комментариям, которые я добавил к тексту сообщения.

Technobrat 11.02.2023 22:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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. Спасибо за отзыв и помощь.

Technobrat 12.02.2023 21:56

Другие вопросы по теме