Использование IN с наборами кортежей в SQL (SQLite3)

У меня есть следующая таблица в базе данных SQLite3:

CREATE TABLE overlap_results (
neighbors_of_annotation varchar(20),
other_annotation varchar(20),
set1_size INTEGER,
set2_size INTEGER,
jaccard REAL,
p_value REAL,
bh_corrected_p_value REAL,
PRIMARY KEY (neighbors_of_annotation, other_annotation)
);

Я хотел бы выполнить следующий запрос:

SELECT * FROM overlap_results WHERE 
(neighbors_of_annotation, other_annotation)
IN (('16070', '8150'), ('16070', '44697'));

То есть у меня есть пара кортежей идентификаторов аннотаций, и я хотел бы получить записи для каждого из этих кортежей. Приглашение sqlite3 выдает мне следующую ошибку:

SQL error: near ",": syntax error

Как правильно выразить это как оператор SQL?


РЕДАКТИРОВАТЬ Я понимаю, что я не объяснил, что я на самом деле после Позвольте мне попробовать еще одну трещину в этом.

Если человек дает мне произвольный список терминов в neighbors_of_annotation что они заинтересованы, я могу написать оператор SQL, как показано ниже:

SELECT * FROM overlap_results WHERE 
neighbors_of_annotation
IN (TERM_1, TERM_2, ..., TERM_N);

Но теперь предположим, что этот человек хочет дать мне пары терминов, если форма (TERM_1,1, TERM_1,2), (TERM_2,1, TERM_2,2),..., (TERM_N,1, TERM_N,2), где TERM_i,1 в neighbors_of_annotation а также TERM_i,2 в other_annotation, Предоставляет ли язык SQL одинаково элегантный способ формулировать запрос для интересующих пар (кортежей)?

Кажется, самое простое решение состоит в том, чтобы создать новую таблицу только для этих пар, а затем объединить эту таблицу с таблицей для запроса и выбрать только те строки, в которых совпадают первые и вторые термины. Создание тонн AND / OR заявления выглядят страшно и подвержены ошибкам.

2 ответа

Решение

Я никогда не видел такой SQL. Если бы он существовал, я бы заподозрил, что это нестандартное расширение. Пытаться:

SELECT * FROM overlap_results
WHERE neighbors_of_annotation = '16070'
AND   other_annotation = '8150'
UNION ALL SELECT * FROM overlap_results
WHERE neighbors_of_annotation = '16070'
AND   other_annotation = '44697';

Другими словами, создайте динамический запрос из ваших кортежей, но вместо этого, как последовательность объединений или как последовательность AND внутри OR:

SELECT * FROM overlap_results
WHERE (neighbors_of_annotation = '16070' AND other_annotation =  '8150')
OR    (neighbors_of_annotation = '16070' AND other_annotation = '44697');

Итак, вместо кода (псевдокод, проверенный только в моей голове, так что отладка - ваша ответственность), такого как:

query  = "SELECT * FROM overlap_results"
query += " WHERE (neighbors_of_annotation, other_annotation) IN ("
sep = ""
for element in list:
    query += sep + "('" + element.noa + "','" + element.oa + "')"
    sep = ","
query += ");"

вместо этого у вас будет что-то вроде:

query  = "SELECT * FROM overlap_results "
sep = "WHERE "
for element in list:
    query += sep + "(neighbors_of_annotation = '" + element.noa + "'"
    query += " AND other_annotation = '" + element.oa + "')"
    sep = "OR "
query += ";"

Мне не известны какие-либо диалекты SQL, которые поддерживают кортежи внутри предложений IN. Я думаю, что вы застряли с:

SELECT * FROM overlap_results WHERE (neighbors_of_annotation = '16070' and other_annotation = '8150') or (neighbors_of_annotation = '16070' and other_annotation = '44697')

Конечно, этот конкретный запрос может быть упрощен до чего-то вроде:

SELECT * FROM overlap_results WHERE neighbors_of_annotation = '16070' and (other_annotation = '8150' or other_annotation = '44697')

Обычно предикаты SQL-предложения WHERE разрешают фильтрацию только по одному столбцу.

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