Потрібно обчислити найбільш підходящу одиницю вимірювання для списку речовин, де речовини наведені в різних (але сумісних) одиничних обсягах.
Таблиця перетворення одиниць
Таблиця перетворення одиниць зберігає різні одиниці та спосіб співвідношення цих одиниць:
id unit coefficient parent_id
36 "microlitre" 0.0000000010000000000000000 37
37 "millilitre" 0.0000010000000000000000000 5
5 "centilitre" 0.0000100000000000000000000 18
18 "decilitre" 0.0001000000000000000000000 34
34 "litre" 0.0010000000000000000000000 19
19 "dekalitre" 0.0100000000000000000000000 29
29 "hectolitre" 0.1000000000000000000000000 33
33 "kilolitre" 1.0000000000000000000000000 35
35 "megalitre" 1000.0000000000000000000000 0
Сортування за коефіцієнтом показує, що parent_id
зв’язує дочірню одиницю з її числовою перевагою.
Цю таблицю можна створити в PostgreSQL за допомогою:
CREATE TABLE unit_conversion (
id serial NOT NULL, -- Primary key.
unit text NOT NULL, -- Unit of measurement name.
coefficient numeric(30,25) NOT NULL DEFAULT 0, -- Conversion value.
parent_id integer NOT NULL DEFAULT 0, -- Relates units in order of increasing measurement volume.
CONSTRAINT pk_unit_conversion PRIMARY KEY (id)
)
Там повинен бути зовнішній ключ від parent_id
до id
.
Таблиця речовин
У таблиці речовин перераховані конкретні кількості речовин. Наприклад:
id unit label quantity
1 "microlitre" mercury 5
2 "millilitre" water 500
3 "centilitre" water 2
4 "microlitre" mercury 10
5 "millilitre" water 600
Таблиця може нагадувати:
CREATE TABLE substance (
id bigserial NOT NULL, -- Uniquely identifies this row.
unit text NOT NULL, -- Foreign key to unit conversion.
label text NOT NULL, -- Name of the substance.
quantity numeric( 10, 4 ) NOT NULL, -- Amount of the substance.
CONSTRAINT pk_substance PRIMARY KEY (id)
)
Проблема
Як би ви створили запит, який знаходить вимірювання, щоб представити суму речовин, використовуючи найменші цифри, що мають ціле число (і необов'язково реальний компонент)?
Наприклад, як би ви повернулися:
quantity unit label
15 microlitre mercury
112 centilitre water
Але не:
quantity unit label
15 microlitre mercury
1.12 litre water
Оскільки 112 має меншу кількість реальних цифр, ніж 1,12, а 112 - менше 1120. Однак у певних ситуаціях використання реальних цифр коротше - наприклад, 1,1 літра проти 110 сантиметрів.
Здебільшого у мене виникають проблеми з підбором правильної одиниці на основі рекурсивного відношення.
Вихідний код
Поки що у мене (очевидно, не працює):
-- Normalize the quantities
select
sum( coefficient * quantity ) AS kilolitres
from
unit_conversion uc,
substance s
where
uc.unit = s.unit
group by
s.label
Ідеї
Чи потрібно це використовувати журнал 10 для визначення кількості цифр?
Обмеження
У підрозділів не всі десятки. Наприклад: http://unitsofmeasure.org/ucum-essence.xml