Python FOR循环声明节中出现语法错误
我试图在Postgres中使用Python FOR循环声明节中出现语法错误,python,sql,postgresql,plpgsql,psycopg2,Python,Sql,Postgresql,Plpgsql,Psycopg2,我试图在Postgres中使用FOR循环来计算数据库中每个地理位置的(变量)范围内的数据平均值。我正在使用python/psycopg2。代码如下: query =''' DECLARE geoids RECORD; BEGIN RAISE NOTICE 'Beginning average calculation'; FOR geoids IN select*from census_blocks WHERE ST_contains((select geom fr
FOR
循环来计算数据库中每个地理位置的(变量)范围内的数据平均值。我正在使用python/psycopg2。代码如下:
query ='''
DECLARE geoids RECORD;
BEGIN
RAISE NOTICE 'Beginning average calculation';
FOR geoids IN select*from census_blocks
WHERE ST_contains((select geom from census_cbsa
WHERE cbsafp10='%s'),census_blocks.geom)
LOOP
INSERT INTO temp_avgs VALUES
(geoids,
select avg(select alljobs from accessibility_results
WHERE geoid=geoids
AND deptime BETWEEN '%s' and '%s'
AND threshold='%s')
END LOOP;
END;
'''
我收到的错误是
psycopg2.ProgrammingError: syntax error at or near "RECORD"
LINE 2: DECLARE geoids RECORD;
如果我删除此DECLARE
语句(因为我相信循环
选择值上的变量会自动声明为记录
),错误将变为:
psycopg2.ProgrammingError: syntax error at or near "RAISE"
LINE 4: RAISE NOTICE 'Beginning average calculation';
我应该如何正确设置此查询的格式?如何将其措辞为单个选择。大概是这样的:
INSERT INTO temp_avgs(geoid, average)
select cb.geoid, avg(aj.alljobs)
from census_blocks cb join
accessibility_results ar
on cb.geoid = ar.geoid
WHERE ST_contains((select geom from census_cbsa WHERE cbsafp10='%s'), cb.geom) and
ar.deptime BETWEEN '%s' and '%s' AND ar.threshold='%s'
group by cb.geoid;
我不确定所有列来自何处,因此表别名有点像猜测。带循环的过程解决方案
您正在使用PL/pgSQL代码,但试图将其表述为SQL查询。那是不可能的
使用语句或(因为要使用参数)创建:
确保在客户机中正确转义引号
- 选择值上的循环变量不会自动声明为任何内容
- 替换不必要的子查询
- 第二个错误msg:的直接原因是plpgsql命令,而不是SQL命令
INSERT
语句就可以了。进一步解开:
INSERT INTO temp_avgs -- you might add a target list for safety. depends ..
SELECT b.*, avg(alljobs)
FROM census_cbsa c
JOIN census_blocks b ON ST_contains(c.geom, b.geom)
JOIN accessibility_results a ON a.geoid = b.geoid
WHERE c.cbsafp10 = %s
AND a.deptime BETWEEN %s AND %s
AND a.threshold = %s
GROUP BY b.geoid; -- assuming b.geoid is the primary key
我曾考虑过将措辞作为单个选择的可能性,但我认为这不可行——数据表结构对于每个地理位置都有许多值(行)。计算整个数据列的平均值将产生一个数字-我需要每个唯一地理位置的平均值,我认为没有循环是无法做到的。@user3757974。哎呀,我遗漏了所有重要的
groupby
子句。那应该是你想要的。
INSERT INTO temp_avgs -- you might add a target list for safety. depends ..
SELECT b.*, avg(alljobs)
FROM census_cbsa c
JOIN census_blocks b ON ST_contains(c.geom, b.geom)
JOIN accessibility_results a ON a.geoid = b.geoid
WHERE c.cbsafp10 = %s
AND a.deptime BETWEEN %s AND %s
AND a.threshold = %s
GROUP BY b.geoid; -- assuming b.geoid is the primary key