Python FOR循环声明节中出现语法错误

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

我试图在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 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命令
基于集合的最优解 这将演示plpgsql函数的基础知识。但是,正如@Gordon已经提供的那样,只需使用一个
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