PostgreSQL空列表VALUES表达式

时间:2019-07-09 16:59:09

标签: django python-3.x postgresql psycopg2

我正在尝试获取点列表,并查询地理空间数据库以查找所有匹配的行。

我有一条经过计算的SQL语句,如下所示:

cursor = connection.cursor()
cursor.execute(
    '''
    SELECT g.ident
    FROM (VALUES %s) AS v (lon, lat)
    LEFT JOIN customers g
    ON (ST_Within(ST_SetSRID(ST_MakePoint(v.lon, v.lat), %s), g.poly_home));
    ''', [AsIs(formatted_points), SRID]
)

以下是formatted_points变量的示例:

(-115.062,38.485), (-96.295,43.771)

因此,当将其插入到SQL表达式中时,VALUES表达式将读取:

(VALUES (-115.062,38.485), (-96.295,43.771)) AS v (lon, lat)

到目前为止,一切都很好。但是,当点列表为空时,VALUES表达式如下所示:

(VALUES ) AS v (lon, lat)

..这导致我收到此错误:

django.db.utils.ProgrammingError: syntax error at or near ")"

换句话说,(VALUES )不是合法的SQL。

这是问题:如何使用VALUES表示空白列表?我可以对此进行特殊处理,并在此函数传递一个空列表时只返回一个空列表,但这似乎并不十分优雅。

我已经看过PostgreSQL manual page中的VALUES,但是我不明白如何构造一个空的VALUES表达式。

1 个答案:

答案 0 :(得分:1)

如果您可以将lons和lats放在单独的数组中,则可以使用带有unnest的数组:

select * from unnest(ARRAY[1, 2, 3]::int[], ARRAY[4, 5, 6]::int[]) as v(lon, lat);
 lon | lat
-----+-----
   1 |   4
   2 |   5
   3 |   6
(3 rows)

select * from unnest(ARRAY[]::int[], ARRAY[]::int[]) as v(lon, lat);
 lon | lat
-----+-----
(0 rows)

您必须将数组转换为适当的类型(可能不是int [])。如果数组不为空,则Postgres会猜测类型,但是如果数组为空,并且您不将其强制转换为特定类型,它将引发错误。