Erlang Mnesia эквивалент SQL выберите из поля где в (value1, value2, value3, …)
у меня есть таблица mnesia с полями, скажем f1, f2, f3. Теперь, если бы я выбрал все строки со значением поля как V1, я бы использовал mnesia:select
и соответствуют спецификациям или простой mnesia:match_object
. Теперь мне нужно выбрать все строки, которые имеют V1, V2, V3 ... или Vn (список произвольной длины) в качестве значения для поля f1. В SQL я бы сделал что-то вроде
SELECT * FROM tablename WHERE f3 IN (V1, V2, V3, ... , Vn)
как это сделать в мнезии?
3 ответов
и для решения этой проблемы, если QLC измеряется как недостаточно эффективный.
> ets:fun2ms(fun ({_,X}=E) when X == a -> E end).
[{{'_',''},[{'==','',a}],['$_']}]
ets: fun2ms-это преобразование синтаксического анализа, которое может перевести некоторые funs в значения matchspec. Я использую его как быстрый способ получить matchspec, который я хочу. Мы получаем список с matchspec, который находит кортеж, где второй элемент является. Мы можем повторить это для других ключей.
Так позволяет заполнить таблицу ets с чем-то, чтобы попробовать это, а затем создать matchspec, который соответствует только элементам со вторым элементом как " a " или "c". (Я вхожу в это
ets:new(foo, [named_table]).
ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]).
Vs = [a,c].
MS = [{{'_',''},[{'==','',V}],['$_']} || V <- Vs].
ets:select(foo, MS).
когда я запускаю это, я получаю:
[{1,a},{3,c}]
христианин указал, хорошее решение, но его можно сделать чуть проще
2> ets:fun2ms(fun ({_,a}=E) -> E end).
[{{'_',a},[],['$_']}]
Так что для вас матч вы можете сделать проще матч spec
4> ets:new(foo, [named_table]).
foo
5> ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]).
true
6> Vs = [a,c].
[a,c]
7> MS = [{{'_',V},[],['$_']} || V <- Vs].
[{{'_',a},[],['$_']},{{'_',c},[],['$_']}]
8> ets:select(foo, MS).
[{1,a},{3,c}]
Если вам нужны "сложные" запросы, то QLC-это краткий способ их изложения. QLC-это синтаксическое преобразование, которое позволяет использовать синтаксис понимания списка для различных таблиц, включая таблицы mnesia.
вы должны включите следующее, Так как оно включает преобразование parse, которое делает QLC возможным в этом исходном файле.
-include_lib("stdlib/include/qlc.hrl").
основная форма запроса выглядит следующим образом, создавая дескриптор запроса, а затем оценивая запрос.
QH = qlc:q([X || X <- Xs]),
qlc:eval(QH).
затем вы можете использовать http://www.erlang.org/doc/man/mnesia.html#table-1 приобрести угловую систему быстрой загрузки QLC таблицы состава в таблице mnesia. Так что ваш запрос может быть реализован следующим образом:
Vs = [V1,V2,...Vn],
QH = qlc:q([X || X <- mnesia:table(tablename),
lists:member(X#tablename.f3, Vs)]),
qlc:eval(QH).
для этого требуется сканирование таблицы, что не очень эффективно. Если у вас есть индекс в столбце f3, вы можете вместо этого повернуть его и запросить сначала записи с f3 = V1, затем V2 и т. д... и слить результаты.
PS
альтернативой является создание довольно сложной спецификации соответствия из вашего списка V-значений и запуск mnesia:select.