Использование кортежей в 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)
Я делаю грубую концептуальную ошибку? Или что?
Ответы
Ответ 1
ваш код работает, если вы делаете это в 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
);
[EDIT]
не указывается намерение:
SELECT a,b FROM aTable
WHERE
EXISTS
(
SELECT *
FROM anotherTable
WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b
);
он несколько хромой, уже более десятилетия MS SQL по-прежнему не имеет первоклассной поддержки кортежей. Конструкция IN кортежа является более читаемой, чем ее аналогичная конструкция EXISTS. Кстати, JOIN также работает (код tster), но если вам нужно что-то более гибкое и надежное будущее, используйте EXISTS.
[EDIT]
говоря о SQLite, я сейчас занимаюсь этим. да, IN кортежи не работают
Ответ 2
вы можете использовать соединение:
SELECT aTable.a, aTable.b FROM aTable
JOIN anotherTable ON aTable.a = anotherTable.a AND aTable.b = anotherTable.b
Ответ 3
Другой альтернативой является использование конкатенации, чтобы сделать ваш 2-кортеж в одно поле:
SELECT a,b FROM aTable
WHERE (aTable.a||'-'||aTable.b) IN
(SELECT (anotherTable.a || '-' || anotherTable.b FROM anotherTable);
... просто помните, что могут произойти плохие вещи, если a или b содержат разделитель '-'