Я храню контакты между различными элементами. Я хочу устранить элементы определенного типа и сохранить новые контакты элементов, которые были взаимосвязаны устраненным элементом.
Вообразите эту проблему. У Вас есть молекула воды, которая находится в контакте с другими молекулами (если контакт является водородной связью, может быть 4 других молекулы вокруг моей воды). Как в следующем изображении (A, B, C, D являются некоторыми другими атомами и точками, означают контакт).
A B
| |
H H
. .
O
/ \
H H
. .
C D
У меня есть информация обо всех точках, и я должен устранить воду в центре и создать записи, описывающие контакты A-C, A-D, A-B, B-C, B-D и C-D.
В настоящее время у меня есть следующая структура в базе данных:
Таблица atoms
:
"id" integer PRIMARY KEY,
"amino" char(3) NOT NULL,
(HOH для воды или другого значения)Таблица contacts
:
"acceptor_id" integer NOT NULL,
(атом близко к моему водороду, здесь C или D)"donor_id" integer NOT NULL,
(здесь A или B)"directness" char(1) NOT NULL,
(это должно быть D для прямого и W для установленного водой),Править: Как посмотрел бы, данные в случае изобразили ранее.
atoms
:
id|atom|amino
1 | O | HOH
2 | N | ARG <- atom A from image
3 | S | CYS <- B
4 | O | SER <- C
5 | N | ARG <- D
contacts
:
donor_id|acceptor_id|directness
1 4 D
1 5 D
2 1 D
3 1 D
Из которого я должен сделать
contacts
:
donor_id|acceptor_id|directness
3 4 W <- B-C
3 5 W <- B-D
2 4 W <- A-C
2 5 W <- A-D
2 3 X <- A-B (These last two rows are escaping me,
4 5 X <- C-D there could be also row D-C, but not
both C-D and D-C. A char 'X' could
be used to mark "no donor/acceptor")
Теперь, я прохожу все контакты, которые имеют donor.amino = "HOH"
. В этом демонстрационном случае это выбрало бы контакты из C и D. Для каждого из этих выбранных контактов я ищу контакты, имеющие то же acceptor_id
как donor_id
в в настоящее время выбираемом контакте. От этой информации я создаю новый контакт. В конце я удаляю все контакты к или от HOH.
Таким образом, я очевидно не могу создать контакты C-D и A-B (другие 4 в порядке).
Если я пробую аналогичный подход - пытающийся найти два контакта, имеющие тот же donor_id, я заканчиваю с дублирующимися контактами (C-D и D-C).
Мне снится кто-то страница долгий SQL-запрос, который получает просто эти шесть требуемых строк.:-)
Однако любые другие идеи приветствуются.
Желательно сохранять информацию о том, кто донор (где возможный), но не строго необходимый.
Большое спасибо всем Вам, кто считал этот вопрос этой точке.
Ну, это сложно предоставить примеры в комментариях, я решил опубликовать ответ:
Если вам нужно следовать исходным данным, нет способа отличить данные из первой структуры от данных из второй. Должно быть дополнительное условие группировки для определения направлений между первой и второй структурой.
sqlite> create table atoms (id INT, atom TEXT, amino TEXT);
sqlite> insert into atoms VALUES (1, 'O', 'HOH');
sqlite> insert into atoms VALUES (2, 'A', 'ARG');
sqlite> insert into atoms VALUES (3, 'B', 'CYS');
sqlite> insert into atoms VALUES (4, 'C', 'SER');
sqlite> insert into atoms VALUES (5, 'D', 'ARG');
sqlite> insert into atoms VALUES (6, 'O1', 'HOH');
sqlite> insert into atoms VALUES (7, 'A1', 'ARG');
sqlite> insert into atoms VALUES (8, 'B1', 'CYS');
sqlite> insert into atoms VALUES (9, 'C1', 'SER');
sqlite> insert into atoms VALUES (10, 'D1', 'ARG');
sqlite> select * from atoms;
1|O|HOH
2|A|ARG
3|B|CYS
4|C|SER
5|D|ARG
6|O1|HOH
7|A1|ARG
8|B1|CYS
9|C1|SER
10|D1|ARG
UPD
Вот исходные данные:
sqlite> .headers ON
sqlite> .mode columns
sqlite> select * from atoms;
id atom amino
---------- ---------- ----------
1 O HOH
2 A ARG
3 B CYS
4 C SER
5 D ARG
6 O1 HOH
7 A1 ARG
8 B1 CYS
9 C1 SER
10 D1 ARG
sqlite> select * from contacts;
donor_id acceptor_id directness
---------- ----------- ----------
1 4 D
1 5 D
2 1 D
3 1 D
6 9 D
6 10 D
7 6 D
8 6 D
Вот запрос:
select
c1.donor_id, c2.acceptor_id, 'W' as directness
from
contacts c1, contacts c2, atoms a
where
c1.acceptor_id = c2.donor_id
and c1.acceptor_id=a.id
and a.amino='HOH'
UNION ALL
select
c1.donor_id, c2.donor_id, 'X' as directness
from
contacts c1, contacts c2, atoms a
where
c1.acceptor_id = c2.acceptor_id
and c1.acceptor_id=a.id
and a.amino='HOH'
and c1.donor_id < c2.donor_id
UNION ALL
select
c1.acceptor_id, c2.acceptor_id, 'X' as directness
from
contacts c1, contacts c2, atoms a
where
c1.donor_id = c2.donor_id
and c1.donor_id=a.id
and a.amino='HOH'
and c1.acceptor_id < c2.acceptor_id;
Вот результат:
donor_id acceptor_id directness
---------- ----------- ----------
2 4 W
2 5 W
3 4 W
3 5 W
7 9 W
7 10 W
8 9 W
8 10 W
2 3 X
7 8 X
4 5 X
9 10 X
Есть одна трудность с вашим объяснением.
Вы начинаете с ориентированного графа, в котором каждое ребро представляет собой соединение X => Y, где X - донор, а Y - акцептор. Таблица атомов
является SQL-представлением этого графа.
Кажется, вам нужно что-то ненаправленное . Таким образом, связь X-Y означает, что X и Y связаны через молекулу воды (или, конечно, некоторые другие разновидности), но что X и Y могут быть как донорами, так и акцепторами. По этой причине ваша последняя таблица имеет двусмысленность (которую вы заметили), так что некоторые ссылки могут появляться в любом случае. Мне кажется, это означает, что заголовки столбцов donor_id
и acceptor_id
в вашем последнем столбце не имеют никакого значения, которое вы объяснили. Конечно, это может быть мое замешательство.
Если все, что вам нужно, это таблица со всеми 6 ссылками в ней, каждая в виде одной строки, но не беспокойтесь об отслеживании донора / акцептора, тогда это работает для меня в sqlite3:
create temporary view hoh_view as
select donor_id as id, atoms.id as hoh_id from contacts, atoms
where acceptor_id=atoms.id and atoms.amino='HOH'
union select acceptor_id as id, atoms.id as hoh_id from contacts, atoms
where donor_id=atoms.id and atoms.amino='HOH';
select a.id, b.id from hoh_view as a, hoh_view as b
where a.id > b.id and a.hoh_id=b.hoh_id;
Где Я использовал временное представление, чтобы прояснить ситуацию. Вы можете объединить все это в один большой запрос, если хотите, заменив каждую ссылку на hoh_view
первым запросом. Мне это кажется немного неприятным, и, возможно, есть способ привести его в порядок.
Если вы действительно хотите отслеживать взаимоотношения донор / акцептор, вам необходимо объяснить, как вы решаете, что делать, когда обе аминокислоты являются акцепторами или донорами (т.е. последние две строки в вашем примере).
Если это не дает того, что вы хотите, то, может быть, я смогу исправить это, и это поможет.