Erlang Mnesia Эквивалент SQL Выбрать из поля ГДЕ IN (значение1, значение2, значение3, ...) - PullRequest
7 голосов
/ 26 мая 2010

У меня есть таблица мнезий с полями, скажем, 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 ]

6 голосов
/ 26 мая 2010

И для решения этой задачи в соответствии со спецификацией соответствия, если QLC измеряется как недостаточно эффективный.

> ets:fun2ms(fun ({_,X}=E) when X == a -> E end).
[{{'_','$1'},[{'==','$1',a}],['$_']}]

ets: fun2ms - это преобразование, которое может преобразовать some приколы в значениях 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 = [{{'_','$1'},[{'==','$1',V}],['$_']} || V <- Vs].

ets:select(foo, MS).

Когда я запускаю это, я получаю:

[{1,a},{3,c}]
4 голосов
/ 01 июня 2010

Кристиан указал хорошее решение, но его можно сделать немного проще

2> ets:fun2ms(fun ({_,a}=E) -> E end).             
[{{'_',a},[],['$_']}]

так что для вас совпадение вы можете сделать более простым соответствием спецификации

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}]
2 голосов
/ 26 мая 2010

Если вам нужны «сложные» запросы, тогда QLC - это краткий способ их сформулировать. QLC - это синтаксический анализ, который позволяет вам использовать синтаксис понимания списка в различных таблицах, включая таблицы мнезий.

Вы должны иметь следующее включение, поскольку оно разрешает синтаксическое преобразование, которое делает возможным 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 в таблице мнезий. Таким образом, ваш запрос может быть реализован следующим образом:

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.

...