将分组的选择结果复制到表

时间:2016-08-21 17:29:56

标签: python postgresql

好的,首先:我对PostgreSQL和编程很新。 所以我有两张桌子。一张桌子(汽车)是:

 id |  brand  | model | price 
----+---------+-------+-------
  1 | Opel    | Astra | 12000
  2 | Citroen | C1    | 12000
  3 | Citroen | C2    | 15000
  4 | Citroen | C3    | 18000
  5 | Audi    | A3    | 20000

另一个是:

 id |  brand  | max_price 
----+---------+-----------
  4 | Opel    |          
  5 | Citroen |          
  6 | Audi    |          

我想做的是,在汽车上做出选择,以便我按品牌分组最高价格,然后我想以最高价格将价格插入代理品牌。 我尝试使用python,这就是我所做的:

cur = conn.cursor()
cur.execute ("""DROP TABLE IF EXISTS temp """)
cur.execute ("""CREATE TABLE temp (brand text, max_price integer)""")
conn.commit()
cur.execute ("""SELECT  cars.brand, MAX(cars.price) FROM cars GROUP BY    brand;""")
results = cur.fetchall()
for results in results:
  cur.execute ("""INSERT INTO temp (brand, max_price) VALUES %s""" % str(results))
  conn.commit()

cur.execute ("""UPDATE max_price SET max_price.max_price=temp.max_price   WHERE max_price.brand = temp.brand;""")
conn.commit()

它卡在更新部分signalling an error max_price.brand = temp.brand

有人能帮助我吗?

编辑:感谢多米诺骨牌的建议我用cur.execute ("""UPDATE max_price SET max_price.max_price=temp.max_price_int from temp WHERE max_price.brand = temp.brand;""")更改了最后一行现在我遇到的问题是,temp.max_price不是一个整数,而是一个元组。所以,为了解决我试图在最后一行之前添加以下代码的问题:

for results in results:
results =results[0]
results = int(results)
cur.execute ("""INSERT INTO temp (max_price_int) VALUES %s""" % str(results))
conn.commit()

它给了我一个错误

cur.execute ("""INSERT INTO temp (max_price_int) VALUES %s""" % str(results)) 
psycopg2.ProgrammingError: syntax error at or near "12000"
LINE 1: INSERT INTO temp (max_price_int) VALUES 12000

12000正好是我想要插入的第一个值!

1 个答案:

答案 0 :(得分:1)

使用cur.execute时,不应使用%运算符。它打开了对SQL注入攻击的查询。

相反,请使用内置查询参数化,如下所示:

cur.execute ("""INSERT INTO temp (max_price_int) VALUES (%s)""",(results,))

请参阅此处的文档:http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

另一种方法是使用SQL在使用with子句的单个查询中进行更新。单个查询看起来像这样:

with max (brand, max_price) as (
  select brand, max(price) from cars
  group by brand
)
update max_price 
   set max_price = max.max_price
from max
where max_price.brand = max.brand
;

在此处阅读有关公用表格表达式(CTE)的更多信息:https://www.postgresql.org/docs/9.5/static/queries-with.html