2011-03-17 122 views
0

在表1中有一列名为calendar_date的记录格式为10/8/2010,在表格2中有一列名为date的列,格式为10/8。 在表2中还有另外两列名为daynoleap,dayleap,表示无线电年或闰年的朱利安日期。现在我需要将这两个列中的一列添加到table1,由列calendar_date的年份确定。如果是2010,它除以4并且有一个余数,所以我将table2的daynoleap列添加到table1的julian_date列。否则,我添加dayleap列。PostgreSQL中子查询返回的多行

我收到一个错误:通过使用下面的代码作为表达式使用子查询返回的多行:(我相信现在的错误来自查询语句)。所有的代码都在一个forloop内,其中我得到了单年的变量(例如2010),monthDate(例如10/8)的记录。

 while int(year)%4 == 0: 
      statement2="UPDATE table1 SET julian_date = (SELECT dayleap FROM table2 WHERE date = '%s') WHERE (SELECT date FROM table2) = '%s'" 
      statement2=statement2 % (monthDate, monthDate) 
      curs2 = conn.cursor() 
      curs2.execute(statement2,) 
      conn.commit() 

显然有代码有问题,以防止它得到单个记录更新。但是因为我已经有了更新语句的WHERE子句,所以我也没有看到语句的问题。我试图将这两个值切换到等号的左侧和右侧等,但没有奏效。有人可以帮助我?

解决方案:
我使用下面的代码解决了这个问题:

statement1='SELECT date FROM table1' 
    curs1.execute(statement1) 
    records1=curs1.fetchall() 
    for record1 in records1: 
     date = record1[0].split('/') 
     monthDate=date[0]+ '/'+date[1] 

     if int(year)%4 == 0: #for leap year 
      statement_tmp = "SELECT dayleap FROM table2 WHERE date = '%s'" % (monthDate) #the date column in table2 is in format of month/date. 
      curs1.execute(statement_tmp) 
      julianDate1 = curs1.fetchall() 
      julianDate = curs1.fetchall()[0][0] 
      statement = "UPDATE table1 SET juliandate = '%s' WHERE date = '%s'" % (julianDate, fullDate) 
      curs1.execute(statement) 
      conn.commit() 

     else: # for nonleap year 
+0

你确定在你的数据库中没有两个相同日期的记录吗?为了使它至少容易出错,你可以给子查询添加一个LIMIT 1 ... – dcn 2011-03-17 20:37:36

回答

0

我通过分割SELECT和UPDATE语句为单独的人来解决。此外,在声明中:SELECT column1 FROM table WHERE column2 = variable .. column2应该在表内,而不是从另一个表。否则,它无法找到正确的记录来选择或更新。提示是解决问题的关键。查看问题中的解决方案。谢谢

1

您正在试图julian_date设置的东西,子查询返回(这是返回多个结果),但是你可以分配多个结果。子查询应只返回一个结果,以便您可以设置julian_date。

你的子查询更改为:

SELECT dayleap FROM table2 WHERE date = '%s' LIMIT 1 

,你可能希望限制1添加到您的第二次查询,以及。

+0

@ mike:是的,它现在可以工作!即时通讯使用print statement2,它打印数百万条记录,这意味着它现在可以工作。但由于某些原因,它只是不会将记录更新到table1。这可能是关于什么的?谢谢 – widget 2011-03-17 20:50:13

+0

可能是你WHE​​RE子句没有找到任何更新结果。 – 2011-03-17 20:57:01

+0

我不知道是否声明:UPDATE表SET列=(SELECT column2 FROM table2 ..)..有道理或没有意义。它应该怎么写? – widget 2011-03-17 21:17:51

2

这是一个非常基本的更新声明。应该是零子查询和相关查询:

UPDATE table1 
    SET julian_date = dayleap 
FROM table2 
WHERE date = %s 

PS:

  • 我不会名称的数据类型(日期)后的列。虽然它允许它以微妙和阴险的方式咬你。
  • 如果来自不可信任的来源,而不仅仅是将其丢失,您希望转义数据。
  • 对于像闰年这样简单的事情,这看起来像很多工作。 PostgreSQL的已经知道:select extract(day from (2003 || '-03-01')::date - '1 day'::interval) = 29在那里你可以paramatize 2003年进入任何一年