Более одной строки, возвращенной подзапросом в PostgreSQL - PullRequest
0 голосов
/ 17 марта 2011

В таблице 1 есть столбец с именем calendar_date, запись в формате 8.10.2010, в таблице 2 есть столбец с именем date, в формате 10/8. В таблице 2 есть два других столбца с именем daynoleap, dayleap, которые указывают номер даты в юлианском году или в високосном году. Теперь мне нужно добавить один столбец из этих двух в table1, определяемый годом столбца calendar_date. Если это 2010, он делится на 4 и имеет остаток, поэтому я добавляю столбец daynoleap в table2 в столбец julian_date в table1. В противном случае я добавляю столбец dayleap к нему.

Я получаю сообщение об ошибке: более одной строки, возвращенной подзапросом, используемым в качестве выражения, с использованием приведенных ниже кодов: (на данный момент, я думаю, ошибка произошла из оператора запроса). Все коды находятся в пределах цикла, в котором я получил единственную запись переменной года (например ,.2010), monthDate (например, 10/10).

      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 для оператора update, я также не вижу проблем с оператором. Я пытался переключить два значения влево и вправо от знака равенства и т. Д., Но не получилось. Кто-нибудь может мне помочь?

Решение:
Я решил эту проблему, используя коды ниже:

    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 голосов
/ 18 марта 2011

Это очень простой оператор обновления. Там должно быть ноль подзапросов и коррелированных запросов:

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 год в любой год
1 голос
/ 17 марта 2011

Вы пытаетесь установить julian_date для чего-то, что возвращает подзапрос (который возвращает более одного результата), однако вы не можете назначить несколько результатов.Подзапрос должен возвращать только один результат, поэтому вы можете SET julian_date.

Измените свой подзапрос на:

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

, и вы также можете добавить LIMIT 1 к вашему второму подзапросу.1006 *

0 голосов
/ 21 марта 2011

Я решил разделить операторы SELECT и UPDATE на отдельные. Кроме того, в операторе: SELECT column1 FROM table WHERE column2 = variable .. предполагается, что column2 находится внутри таблицы, а не из другой таблицы. В противном случае он не сможет найти нужные записи для выбора или обновления. Там советы являются ключом к решению проблемы. Смотрите решение в вопросе. Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...