Используя В с наборами кортежей в 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 операторы выглядят страшными и подверженными ошибкам.

6
задан Lukas Eder 12 April 2013 в 14:04
поделиться

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');

Итак, вместо кода (псевдокод, проверенный только в моем head, поэтому отладка - это ваша ответственность), например:

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 += ";"
4
ответ дан 17 December 2019 в 02:26
поделиться

Я не знаю ни одного диалекта 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-clause позволяют фильтровать только один столбец.

2
ответ дан 17 December 2019 в 02:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: