BeamSQL Group By проблема запроса со значением Float
Пытался получить уникальное значение из таблицы BigQuery, используя BeamSQL в Google Dataflow. С помощью предложения Group By реализовано условие в BeamSQL (пример запроса ниже). Один из столбцов имеет тип данных с плавающей точкой. Выполняя работу получил ниже исключений,
Вызывается: org.apache.beam.sdk.coders.Coder$NonDeterministicException: org.apache.beam.sdk.coders.RowCoder@81d6d10 не является детерминированным, поскольку: все поля должны иметь детерминистическую кодировку. Вызывается: org.apache.beam.sdk.coders.Coder$NonDeterministicException: FloatCoder не является детерминированным, потому что: не гарантируется, что кодировки с плавающей точкой будут детерминированными.
BeamSQL Query:
PCollection ST = mainColl.apply (SqlTransform.query ("ВЫБЕРИТЕ ID, ПУНКТ, УНИТПРИЦ ИЗ ГРУППЫ PCOLLECTION ПО ID, ПУНКТ, УНИТПРИЦ"));
Было бы хорошо, если бы кто-нибудь помог мне решить эту проблему.
Обратите внимание: если мы удалим столбец с плавающей точкой, запрос BeamSQL будет работать нормально.
1 ответ
Это указывает на то, что вы не должны использовать значения с плавающей запятой (в этом случае, вероятно, UNITPRICE
value) в схеме агрегации (group by), потому что их выходные данные являются недетерминированными (то есть могут изменяться в зависимости от изменения точности). Например, рассмотрим этот пример:
WITH
data AS (
SELECT 100 AS id, 'abc' as item, 0.3448473362800000001 AS unitprice
UNION ALL
SELECT 200 AS id, 'xyz' as item, 0.49300013 AS unitprice
UNION ALL
SELECT 500 AS id, 'pqr' as item, 0.67322332200000212 AS unitprice
)
select id, item, unitprice from data
group by id, item, unitprice
Выход для этого будет:
100 abc 0.34484733628
200 xyz 0.49300013
500 pqr 0.6732233220000021
в котором unitprice
значения выглядят немного иначе.
Чтобы избежать этого, вы можете пойти двумя путями:
- Вы можете разыграть свою цену в виде строки, а затем продолжить группировку. Что-то вроде
cast(unitprice as string) as unitprice
в вашем запросе. - Вы можете просто выбрать сохранить
unitprice
как не сгруппированный объект (что является логическим вариантом в большинстве случаев), и просто сделатьmax(unitprice) as unitprice
или жеavg(unitprice) as unitprice
в вашем запросе при группировании поid, item
,
Надеюсь это поможет.