首页 文章

PostgreSQL中的子查询返回了多行

提问于
浏览
0

在table1中有一个名为calendar_date的列,该记录的格式为10/8/2010,在table2中有一个名为date的列,格式为10/8 . 在表2中还有另外两列名为daynoleap,dayleap,它表示noleap年或闰年的julian日期数 . 现在我需要将这两个列中的一列添加到table1,由列calendar_date的年份确定 . 如果它是2010,它除以4并且有一个余数,所以我将table2的daynoleap列添加到table1的julian_date列 . 否则我添加dayleap列 .

我收到一个错误:使用以下代码的子查询返回的多行:(我相信错误来自查询语句) . 所有代码都在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

3 回答

  • 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 你可以将2003年的任何一年变为二年级

  • 0

    您正在尝试将julian_date设置为子查询返回的内容(返回多个结果),但是您无法分配多个结果 . 子查询应该只返回一个结果,因此您可以设置julian_date .

    将子查询更改为:

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

    并且您可能还想将LIMIT 1添加到第二个子查询中 .

  • 1

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

相关问题