Обновить значение столбца значением из другой строки, где конкретный столбец совпадает - PullRequest
0 голосов
/ 22 мая 2018

У меня есть таблица:

CREATE TABLE STOTMARS
(
  KODAS integer NOT NULL,
  PUNKTAS varchar(50) NOT NULL,
  MARS varchar(10) NOT NULL,
  EILNR integer NOT NULL,
  METRAI integer NOT NULL,
  VIDGR integer NOT NULL,
  TARPINIS varchar(1),
  CONSTRAINT STOTMARS_ID PRIMARY KEY (KODAS,PUNKTAS,MARS,EILNR)
);
CREATE INDEX STOTMARS_EILNR ON STOTMARS (EILNR);
CREATE INDEX STOTMARS_KODAS ON STOTMARS (KODAS);
CREATE INDEX STOTMARS_MARS ON STOTMARS (MARS);
CREATE INDEX STOTMARS_PUNKTAS ON STOTMARS (PUNKTAS);
GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
 ON STOTMARS TO  SYSDBA WITH GRANT OPTION;

Мне нужно обновить значение EILNR в строках, где PUNKTAS = 'Dvaro st.3' со значением EILNR из строки с тем же значением KODAS и значением PUNKTAS 'Centro st.1 '

До сих пор я пытался:

update STOTMARS a
set a.EILNR = (
    select
        b.EILNR
    from STOTMARS b
    where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
)
where a.PUNKTAS = 'Dvaro st.3'

но это дает мне ошибку:

Executing statement...
Error: *** IBPP::SQLException ***
Context: Statement::Execute( update STOTMARS a
set a.EILNR = (
    select
        b.EILNR
    from STOTMARS b
    where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
)
where a.PUNKTAS = 'Dvaro st.3' )
Message: isc_dsql_execute2 failed

SQL Message : -625
The insert failed because a column definition includes validation constraints.

Engine Code    : 335544347
Engine Message :
validation error for column EILNR, value "*** null ***"


Total execution time: 0.000s

Чтобы сделать запрос более понятным:

select
a.MARS, a.EILNR, b.EILNR
from STOTMARS a
join STOTMARS b
on a.MARS = b.MARS and b.PUNKTAS = 'Dvaro st.3'
where a.PUNKTAS = 'Centro st.1'

дает мне таблицу, в которой каждое третье значение столбца должно быть заменено значением второго столбца этой строки.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Вы можете избежать NULL несколькими способами.Одним из способов является замена значения на соответствующее значение:

update STOTMARS a
    set a.EILNR = (select coalesce(max(b.EILNR), 0)
                   from STOTMARS b
                   where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
                  )
    where a.PUNKTAS = 'Dvaro st.3';

Или, альтернативно, добавьте предложение сравнения:

update STOTMARS a
    set a.EILNR = (select coalesce(max(b.EILNR), 0)
                   from STOTMARS b
                   where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
                  )
    where a.PUNKTAS = 'Dvaro st.3' and
          (select b.EILNR
           from STOTMARS b
           where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
          ) is not null;

Обратите внимание, что здесь не используется not exists, поэтомуможно учитывать NULL значение sin EILNR.

0 голосов
/ 22 мая 2018

Проблема в том, что внутреннее выделение не дает строк, и поэтому обновление пытается присвоить null, потому что применяемые условия являются взаимоисключающими, и это не удается из-за ограничения NOT NULL на EILNR:

update STOTMARS a
set a.EILNR = (
    select
        b.EILNR
    from STOTMARS b
    where a.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS
)
where a.PUNKTAS = 'Dvaro st.3'

a.PUNKTAS не может быть 'Centro st.1' и 'Dvaro st.3' одновременно.Условие во внутреннем выделении, вероятно, должно использовать b.PUNKTAS:

where b.PUNKTAS = 'Centro st.1' and a.MARS = b.MARS

Вы также можете рассмотреть возможность использования MERGE вместо этого коррелированного обновления.

...