Использование кортежей в SQL в пункте

Учитывая базу данных, как это:

BEGIN TRANSACTION;
CREATE TABLE aTable (
a STRING,
b STRING);
INSERT INTO aTable VALUES('one','two');
INSERT INTO aTable VALUES('one','three');
CREATE TABLE anotherTable (
a STRING,
b STRING);
INSERT INTO anotherTable VALUES('one','three');
INSERT INTO anotherTable VALUES('two','three');
COMMIT;

Я хотел бы сделать что-то вроде

SELECT a,b FROM aTable
WHERE (aTable.a,aTable.b) IN
(SELECT anotherTable.a,anotherTable.b FROM anotherTable);

Чтобы получить ответ "один", "три", но я получаю "рядом", ": синтаксическая ошибка"

Это возможно в любой разновидности SQL? (Я использую sqlite)

Я делаю грубую концептуальную ошибку? Или что?

3 ответа

Решение

Ваш код работает, если вы делаете это в PostgreSQL или Oracle. на MS SQL не поддерживается

использовать этот:

SELECT a,b FROM aTable
WHERE 
-- (aTable.a,aTable.b) IN -- leave this commented, it makes the intent more clear
EXISTS
(
    SELECT anotherTable.a,anotherTable.b -- do not remove this too, perfectly fine for self-documenting code, i.e.. tuple presence testing
    FROM anotherTable
    WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b
);

[РЕДАКТИРОВАТЬ]

без указания намерения:

SELECT a,b FROM aTable
WHERE     
EXISTS
(
    SELECT *
    FROM anotherTable
    WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b
);

Это несколько неубедительно, вот уже более десяти лет MS SQL по-прежнему не имеет первоклассной поддержки кортежей. Конструкция IN tuple более удобочитаема, чем аналогичная конструкция EXISTS. Кстати, JOIN также работает (код tster), но если вам нужно что-то более гибкое и ориентированное на будущее, используйте EXISTS.

[РЕДАКТИРОВАТЬ]

Говоря о SQLite, я в последнее время балуюсь этим. да, IN кортежей не работает

Вы можете использовать соединение:

SELECT aTable.a, aTable.b FROM aTable
JOIN anotherTable ON aTable.a = anotherTable.a AND aTable.b = anotherTable.b

Другой альтернативой является использование конкатенации, чтобы превратить ваш 2-кортеж в одно поле:

SELECT a,b FROM aTable
WHERE (aTable.a||'-'||aTable.b) IN
(SELECT (anotherTable.a || '-' || anotherTable.b FROM anotherTable);

... просто знайте, что плохие вещи могут случиться, если a или b содержат разделитель '-'

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