Выберите значения из одного столбца, которые имеют значение в другом столбце - PullRequest
1 голос
/ 20 марта 2020

Вот проблема. База данных описывает симметричные и переносимые отношения между объектами (генами разных видов). Если ген X вида 1 относится к гену Y вида 2, а ген Y вида 2 относится к гену Z вида 3, то ген X вида 1 относится к гену Z вида 3.

Вот пример таблицы:

species1 gene1 species2 gene2
2        Y     1        X
2        Y     3        Z

Теперь вот что я хочу сделать. Для заданных видов 1 и 3 (оба в столбце видов2) найдите все гены в столбце ген2, для которых в столбце ген 1 есть общее значение.

По сути, это вывод, который я хотел бы получить:

X  Z

... для каждой пары, которая удовлетворяет этому условию.

Обратите внимание, что каждый идентификатор гена уникально присутствует только в одном виде.

Объяснение: столбец видов1 содержит несколько виды "hub" (как люди). Поэтому, если я хочу найти ген крысы, совпадающий с геном мыши Card9, есть две возможности: (i) в геноме человека нет совпадения, и в этом случае будет совпадение крысы в ​​столбце gene1, или ген мыши будет быть в gene1 и ген крысы в ​​столбце gene2; (ii) существует совпадение в геноме человека (или в каком-либо другом), и в этом случае мне сначала нужно найти совпадение в геноме человека в столбце gene1, а затем найти совпадение с этим геном в геноме крысы в ​​столбце gene2.

Очевидно, я представляю, что смогу сделать это за пределами SQL:

  1. Выбрать все гены в столбце gene2 из вида 1
  2. Выбрать все гены в столбце gene2 вида 3
  3. Для каждого гена вида 1 найдите соответствующие столбцы в столбце gene1, для которого столбец вида 2 равен 3.

Однако я уверен, что есть умный оператор SQL, который может это сделать.

В базе данных около 5 миллионов строк.

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

Вы можете сделать это с помощью самостоятельного соединения:

select t1.gene2 result1, t2.gene2 result2 
from tablename t1 inner join tablename t2
on t2.gene1 = t1.gene1
where t1.species2 = 1 and t2.species2 = 3

См. Демоверсию . Другой способ сделать это с агрегацией:

select min(gene2) result1, max(gene2) result2
from tablename
where species2 in (1, 3)
group by gene1
having result1 <> result2;

См. Демо 1010 *. Результаты:

| result1 | result2 |
| ------- | ------- |
| X       | Z       |
2 голосов
/ 20 марта 2020

Если я правильно понимаю, это самостоятельное соединение:

select distinct g1.gene2
from genes g1 join
     genes g3
     on g1.species2 = 1 and
        g3.species2 = 3 and
        g1.gene2 = g3.gene2 and
        g1.gene1 = g3.gene1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...