Как сравнить строки как int в модели EAV

Я реализовал шаблон EAV db как часть poc в postgres. Это следующая иллюстрация:

entity:
id, primary key 
firstName, varchar
lastName, varchar
tenantId, int, b-tree indexed

attribute:
id, primary key
label, varchar
type, varchar, (enumerated as string from java enum , NUMERIC, TEXT, DATE)

attribute_value:
id, primary key 
attribute_id, fk reference attribute primary key
entity_id, fk reference entity primary key
value, varchar

Теперь проблема, с которой я сталкиваюсь, заключается в сравнении значений в объединенных таблицах. Например,

how do I check whether an attribute with label = 'marks12' has value <
100

Сравнение value::int не решает проблему, поскольку есть другие атрибуты, такие как gender, которые нельзя преобразовать в значение int. Как мне выполнить такие ценностно-ориентированные условия в приведенной выше модели проектирования eav.

PS: Я открыт для другого дизайна БД, который позволяет отображать/хранить динамические атрибуты в СУБД.

Примечание: сущность и атрибут также должны иметь первичные ключи.

wildplasser 03.02.2019 13:23

да, они делают. Обновлю иллюстрацию.

Dota2 03.02.2019 14:30
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
2
150
1

Ответы 1

Вам нужен динамическая команда. Функция должна выполнять эту работу:

create or replace function eval_condition(attr text, a_type text, op text, val text)
returns boolean language plpgsql immutable as $$
declare
    result boolean;
begin
    execute format(
        'select %L::%s %s %L::%s',
        attr, a_type, op, val, a_type)
    into result;
    return result;
end $$;

Примеры:

with example(attr, a_type, op, val) as (
values
    ('100',        'int',     '>',    '50'),
    ('2019-01-01', 'date',    '>',    '2019-01-02'),
    ('some text',  'text',    'like', 'some%'),
    ('99.99',      'numeric', '<',    '99.99')
)
select
    attr, a_type, op, val,
    eval_condition(attr, a_type, op, val)
from example;

    attr    | a_type  |  op  |    val     | eval_condition 
------------+---------+------+------------+----------------
 100        | int     | >    | 50         | t
 2019-01-01 | date    | >    | 2019-01-02 | f
 some text  | text    | like | some%      | t
 99.99      | numeric | <    | 99.99      | f
(4 rows)    

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