SQLite中是否可以使用IN运算符用于元组?

3
我有一张名为"elevation"的表格,包含以下列:
  • lat: 双精度浮点数 (主键)
  • long: 双精度浮点数 (主键)
  • value: 双精度浮点数
当我使用以下语法时,会出现“行值被误用”错误。
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 运算符不能用于元组?


是的。第一种语法不起作用,而第二种语法可以正常工作。 - Cl00e9ment
3个回答

2
如果您只有几个坐标,可以直接使用IN而不是使用临时表(但如果您有大量坐标,则该方法更好,特别是在表上建立索引)。您的尝试非常接近:
SELECT *
FROM elevation
WHERE (lat, long) IN (VALUES (29.42682, 81.774118), (29.63561, 81.622355));

1
是的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),但这在这里不是必要的。

我已经更正了我的答案,因为Shawn揭示了可以指定文字表行,但是我仍然保留了它,因为其他答案涉及到这一点。 - C Perkins

0

感谢ShawnC Perkins。我会在这里总结你们的答案(如果我犯了错误,请告诉我)。

所以有两种方法可以做到这一点。

“优雅的方式”(Shawn的答案):
它使用VALUES关键字。

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

而优化的方法(C Perkins's answer)在需要查询大量数据时非常有用:
它使用了一个临时表。

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接