Можно ли использовать оператор IN для пар в SQLite? - PullRequest
3 голосов
/ 05 июля 2019

У меня есть таблица с именем «высота» со следующими столбцами:

  • лат: двойной (ключ)
  • длинный: двойной (ключ)
  • значение: double

Когда я использую следующий синтаксис, я получаю ошибку «неправильно используется значение строки».

SELECT *
FROM elevation
WHERE (lat, long) IN ((29.42682, 81.774118), (29.63561, 81.622355))

Пока работает этот синтаксис:

SELECT *
FROM elevation
WHERE (lat, long) = (29.42682, 81.774118) OR (lat, long) = (29.63561, 81.622355)

Значит ли это, что оператор IN нельзя использовать для пар?

Ответы [ 3 ]

2 голосов
/ 05 июля 2019

Если у вас есть только несколько координат, вы можете использовать их непосредственно с IN вместо использования временной таблицы (но если у вас есть много, этот подход лучше, особенно с индексом в таблице).Вы были так близки к вашей попытке:

SELECT *
FROM elevation
WHERE (lat, long) IN (VALUES (29.42682, 81.774118), (29.63561, 81.622355));
1 голос
/ 05 июля 2019

Да , оператор IN может использоваться с парами слева. В более общем смысле, левая часть может быть значением строки с несколькими столбцами. Смотри https://www.sqlite.org/rowvalue.html.

Альтернативой типизации повторяющегося списка операторов OR является создание временной таблицы со списком литеральных значений, которые можно «запросить» в выражении подзапроса. Индексы также могут быть добавлены в временную таблицу, чтобы сделать ее более эффективной.

CREATE TEMP TABLE IF NOT EXISTS coordinates (lat, long, UNIQUE (lat, long));
INSERT OR IGNORE INTO coordinates VALUES (29.42682, 81.774118), (29.63561, 81.622355);
SELECT *
FROM elevation
WHERE (lat, long) IN coordinates;

Обратите внимание на более короткую ссылку, поскольку временная таблица содержит одинаковое количество полей. Можно использовать более подробный WHERE (lat, long) IN (SELECT * FROM coordinates), но здесь это не обязательно.

0 голосов
/ 06 июля 2019

Благодаря Шон и C Перкинс .Я обобщу ваши ответы здесь (скажите мне, если я допустил ошибку).

Так что есть два способа сделать это.

«Элегантный способ» ( ответ Шона *)1010 *):
Используется ключевое слово VALUES.

SELECT *
FROM elevation
WHERE (lat, long) IN (VALUES (29.42682, 81.774118), (29.63561, 81.622355));

И оптимизированный способ ( C ответ Перкинса ), полезен при наличии большого количества данных для запроса:
Используется временная таблица.

CREATE TEMP TABLE IF NOT EXISTS coordinates (lat, long);
DELETE FROM coordinates;
INSERT INTO coordinates VALUES (29.42682, 81.774118), (29.63561, 81.622355);
SELECT *
FROM elevation
WHERE (lat, long) IN coordinates;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...