SQL在同一个表中更新多个具有多个值的行

时间:2014-10-31 12:11:34

标签: sql sql-server

我已经搜索过这个网站并发现了一些帖子,但没有任何内容适合我的账单。

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和actual_ *列之外,行是相同的。我要做的是首先设置'2014-08-31 00:00:00.000'的所有prev_year_end actual_ *值,以匹配prev_year_end'2014-02-28 00:00:00.000的actual_ *值。 (我希望这是有道理的)

到目前为止,我已尝试使用以下内容进行更新:

    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.

从这一点开始,我有点陷入困境,想知道是否有人会成为救生员并提出任何建议?

2 个答案:

答案 0 :(得分:0)

我认为您想要在临时表中进行内部联接,然后删除要替换的任何行。通过从临时表中插回值来完成它。

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)

如果您担心自己的删除。我会按照Select * FROM #Temptbl跟进第一步,以便在删除之前查看结果。

答案 1 :(得分: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);