2014-10-31 6 views
1

Я просмотрел этот сайт и нашел несколько сообщений, но ничего, что вполне подходит для счета.SQL обновляет несколько строк с несколькими значениями в одной таблице

company_no site_no sam_code cost_code prev_year_end period_end_date prev_period_end ledger_type_cnp actual_value actual_fcv actual_fav actual_fcq actual_faq 
G1 51 6 0 2014-02-28 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM 791.94 791.94 NULL 0 NULL 
G1 51 6 0 2014-08-31 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM 791.94 791.94 NULL 0 NULL 
G1 51 6 GIE 2014-02-28 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM -832.14 -832.14 0 0 0 
G1 51 6 GIE 2014-08-31 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM -791.94 -791.94 0 0 0 
G1 51 7 0 2014-02-28 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM -1157.32 -1157.32 NULL 0 NULL 
G1 51 7 0 2014-08-31 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM -1157.32 -1157.32 NULL 0 NULL 
G1 51 7 L01 2014-02-28 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM 1157.32 1157.32 NULL 3570 NULL 
G1 51 7 L01 2014-08-31 00:00:00.00 2015-02-28 00:00:00.00 2015-01-31 00:00:00.00 NOM 1157.32 1157.32 NULL 3570 NULL 

Извинения за приведенную выше таблицу, я попытался прикрепить изображение, но не имел точек репутации, чтобы сделать это.

Моя проблема в том, что у меня есть дублирование в таблице dnl. Строки идентичны, за исключением столбцов prev_year_end и фактических столбцов. То, что я хочу сделать, это прежде всего установить все значения prev_year_end actual_ * для '2014-08-31 00: 00: 00.000', чтобы соответствовать фактическим значениям * для prev_year_end '2014-02-28 00: 00: 00.000. (Я надеюсь, что имело смысл)

До сих пор я пытался обновление с:

update dnl 
set actual_value = 
    (select actual_value 
    from dnl where (period_end_date <= '2015-02-28 00:00:00.000' 
    and period_end_date >= '2014-09-30 00:00:00.000') 
    and prev_year_end = '2014-02-28 00:00:00.000' 
    and company_no = 'G1') 
where 
    (period_end_date <= '2015-02-28 00:00:00.000' 
    and period_end_date >= '2014-09-30 00:00:00.000') 
and prev_year_end = '2014-08-31 00:00:00.000' 
and company_no = 'G1' 

и с:

update a 
set a.actual_value = 
    (select b.actual_value 
    from dnl b where (b.period_end_date <= '2015-02-28 00:00:00.000' 
    and b.period_end_date >= '2014-09-30 00:00:00.000') 
    and b.prev_year_end = '2014-02-28 00:00:00.000' 
    and b.company_no = 'G1') 
FROM dnl a 
INNER JOIN dnl b 
     ON a.period_end_date = b.period_end_date 
where 
    (a.period_end_date <= '2015-02-28 00:00:00.000' 
    and a.period_end_date >= '2014-09-30 00:00:00.000') 
and a.prev_year_end = '2014-08-31 00:00:00.000' 
and a.company_no = 'G1' 

Но каждый выпадать с сообщением:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 
The statement has been terminated. 

С этого момента я немного застрял, и мне было интересно, если кто-нибудь будет спасателем жизни и предложит любой совет, пожалуйста?

+0

Посмотрите на результат подзапроса 'select .actual_value ...'. Действительно ли это возвращает несколько строк? Если это так, исправьте это. –

+0

Привет, Майк, спасибо за ответ. Это возвращает более 1 результата. Моя проблема заключается в том, что дублирование произошло до более чем 7000 строк, поэтому изменить каждую строку по отдельности нецелесообразно. Я пытаюсь наложить результаты для prev_year_end 2014-02-28 в верхней части 2014-08-31, так как все остальное одинаково, так что в конечном итоге все строки с prev_year_end 2014-02-28 можно удалить – PDrennan

+1

You потерять суть. Если вы возвращаете несколько строк, какие из них должны использовать dbms для обновления «actual_value»? Используйте соединение или добавьте больше столбцов в предложение WHERE в подзапросе (возможно, company_no, site_no, sam_code и cost_code). –

ответ

0

Я думаю, что вы хотите сделать внутреннее соединение в таблице temp, а затем удалить любую из строк, которые вы хотите заменить. Завершите его, вставив обратно свои значения из таблицы temp.

SELECT A.column1, A.column2, B.column3 as AcolumnName 
INTO #Temptbl 
FROM tbl A 
JOIN tbl B ON XXXX 

Заменить XX в вашем состоянии присоединиться, я не слишком уверен, что на то, что вы присоединяетесь с на основе вашего описания, я бы сказал, что есть дата участие. Затем добавьте удаление к клеткам, которые вы хотите заменить следует повторно вставьте ..

DELETE FROM tbl 
WHERE datecondition 

INSERT INTO tbl (SELECT * FROM #Temptbl) 

Если вы беспокоитесь о своем удалении. Я бы выполнил шаг 1 с помощью Select * FROM #Temptbl, чтобы увидеть результаты перед удалением.

0

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

update dnl 
set actual_value = (select actual_value from dnl d where d.company_no = dnl.company_no and d.site_no = dnl.site_no and d.sam_code = dnl.sam_code and d.cost_code = dnl.cost_code and d.prev_year_end = '2014-02-28 00:00:00.000'), 
    actual_fcv = (select actual_fcv from dnl d where d.company_no = dnl.company_no and d.site_no = dnl.site_no and d.sam_code = dnl.sam_code and d.cost_code = dnl.cost_code and d.prev_year_end = '2014-02-28 00:00:00.000'), 
    actual_fav = (select actual_fav from dnl d where d.company_no = dnl.company_no and d.site_no = dnl.site_no and d.sam_code = dnl.sam_code and d.cost_code = dnl.cost_code and d.prev_year_end = '2014-02-28 00:00:00.000'), 
    actual_fcq = (select actual_fcq from dnl d where d.company_no = dnl.company_no and d.site_no = dnl.site_no and d.sam_code = dnl.sam_code and d.cost_code = dnl.cost_code and d.prev_year_end = '2014-02-28 00:00:00.000'), 
    actual_faq = (select actual_faq from dnl d where d.company_no = dnl.company_no and d.site_no = dnl.site_no and d.sam_code = dnl.sam_code and d.cost_code = dnl.cost_code and d.prev_year_end = '2014-02-28 00:00:00.000') 
where prev_year_end = '2014-08-31 00:00:00.000'; 


Вы получите больше ответов при включении CREATE TABLE и INSERT заявления.

create table dnl (
    company_no char(2), 
    site_no integer, 
    sam_code integer, 
    cost_code varchar(5), 
    prev_year_end timestamp, 
    period_end_date timestamp, 
    prev_period_end timestamp, 
    ledger_type_cnp char(3), 
    actual_value float, 
    actual_fcv float, 
    actual_fav float, 
    actual_fcq float, 
    actual_faq float 
); 

insert into dnl values 
('G1', 51, 6, '0', '2014-02-28 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', 791.94, 791.94, NULL, 0, NULL), 
('G1', 51, 6, '0', '2014-08-31 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', 791.94, 791.94, NULL, 0, NULL), 
('G1', 51, 6, 'GIE', '2014-02-28 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', -832.14, -832.14,  0, 0, 0), 
('G1', 51, 6, 'GIE', '2014-08-31 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', -791.94, -791.94,  0, 0, 0), 
('G1', 51, 7, '0', '2014-02-28 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', -1157.32, -1157.32, NULL, 0, NULL), 
('G1', 51, 7, '0', '2014-08-31 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', -1157.32, -1157.32, NULL, 0, NULL), 
('G1', 51, 7, 'L01', '2014-02-28 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', 1157.32, 1157.32, NULL, 3570, NULL), 
('G1', 51, 7, 'L01', '2014-08-31 00:00:00.00', '2015-02-28 00:00:00.00', '2015-01-31 00:00:00.00', 'NOM', 1157.32, 1157.32, NULL, 3570, NULL); 
Смежные вопросы