目前,我有此记录
InvoiceList表
InvoiceID StoreCustomerID IssuedDate Amount IsPenalty EmployeeID
----------- --------------- ---------- ----------- ----------- -----------
1 13 2007-01-12 244 0 41
2 31 2007-04-05 81 0 34
3 23 2007-01-09 184 0 46
4 28 2007-11-21 231 0 17
5 36 2006-09-19 121 0 22
6 28 2006-10-24 240 0 17
7 15 2006-12-11 193 0 47
8 21 2007-01-15 172 0 4
InvoiceID
自动递增。我想要做的是通过增加前一行的日期来更新IssuedDate
。我想像这样更新它
InvoiceID StoreCustomerID IssuedDate Amount IsPenalty EmployeeID
----------- --------------- ---------- ----------- ----------- -----------
1 13 2007-01-12 244 0 41
2 31 2007-01-13 81 0 34
3 23 2007-01-14 184 0 46
4 28 2007-01-15 231 0 17
5 36 2007-01-16 121 0 22
6 28 2007-01-17 240 0 17
7 15 2007-01-18 193 0 47
8 21 2007-01-19 172 0 4
目前我有这个选择声明并且运作良好。但是我如何使用它来更新IssuedDate
?
WITH SequenceDate AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY IssuedDate) RowNumber
FROM Invoice
)
SELECT RowNumber, DATEADD(d, RowNumber - 1, b.IssuedDate)
FROM SequenceDate
ORDER BY RowNumber
更新1
对于第一篇文章,我非常抱歉,因为给我的指示不正确。日期不应增加,因为我们不允许更改表中的记录,除非我们只能按升序重新排列日期。应该是。
InvoiceID StoreCustomerID IssuedDate Amount IsPenalty EmployeeID
----------- --------------- ---------- ----------- ----------- -----------
1 13 2006-09-19 244 0 41
2 31 2006-10-24 81 0 34
3 23 2006-12-11 184 0 46
4 28 2007-01-09 231 0 17
5 36 2007-01-12 121 0 22
6 28 2007-01-15 240 0 17
7 15 2007-04-05 193 0 47
8 21 2007-11-21 172 0 4
答案 0 :(得分:7)
如果你知道序列中的第一个日期,你可以简单地将Row_Number添加到int:
; WITH SequenceDate AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY IssuedDate) RowNumber,
MIN(IssuedDate) over () FirstDate
FROM Invoice
)
UPDATE SequenceDate
SET IssuedDate = DATEADD(d, RowNumber - 1, FirstDate)
Here is Sql Fiddle with example
<强>更新强>:
to match first question's output exactly:
; WITH SequenceDate AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY InvoiceID) RowNumber
FROM Invoice
)
UPDATE SequenceDate
SET IssuedDate = DATEADD(d, RowNumber - 1,
(select IssuedDate
from Invoice
where InvoiceID = 1))
And to rearange dates to follow InvoiceID:
; WITH SequenceDate AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY InvoiceID) RowNumber,
ROW_NUMBER() OVER (ORDER BY IssuedDate) DateNumber
FROM Invoice
)
UPDATE SequenceDate
SET IssuedDate = d.IssuedDate
from SequenceDate d
where SequenceDate.RowNumber = d.DateNumber
答案 1 :(得分:3)
首先,您要使用第一个插入日期而不是最小值,然后您应该尝试这样的事情:
WITH SequenceDate AS
(
SELECT InvoiceID, ROW_NUMBER() OVER (ORDER BY IssuedDate) AS RowNumber
FROM Invoice
)
UPDATE InvoiceList
SET InvoiceList.IssuedDate = DATEADD(d, SequenceDate.RowNumber - 1, b.IssuedDate)
FROM SequenceDate
INNER JOIN InvoiceList ON SequenceDate.InvoiceID = InvoiceList.InvoiceID
CROSS JOIN (SELECT IssuedDate
FROM InvoiceList
WHERE InvoiceID = 1) b
SQL Fiddle已附上。
答案 2 :(得分:2)
您可以直接从Invoice
加入SequenceDate
表。
WITH SequenceDate AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY IssuedDate) RowNumber
FROM Invoice
)
UPDATE Invoice
SET [IssuedDate] = DATEADD(d, RowNumber - 1, b.IssuedDate)
FROM Invoice a INNER JOIN [SequenceDate] b
ON a.[InvoiceID] = b.[RowNumber]
如果是这种情况,那么试试这个
WITH SequenceDate AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY IssuedDate) RowNumber
FROM Invoice
)
UPDATE Invoice
SET [IssuedDate] = b.IssuedDate
FROM Invoice a INNER JOIN [SequenceDate] b
ON a.[InvoiceID] = b.[RowNumber]
答案 3 :(得分:1)
更新:以下是陈旧的答案,答案是根据OP的原始问题做出的:
为了获得正确的输出,这是最短的:http://www.sqlfiddle.com/#!3/6aa22/1
SELECT * FROM INVOICE;
WITH FirstDate AS
(
SELECT row_number() over(order by InvoiceID) rn, IssuedDate
FROM Invoice
)
,UpdatedDate as
(
select i.InvoiceID, i.IssuedDate, dateadd(d, row_number() over(order by i.InvoiceID) - 1, fd.IssuedDate) as NewDate
from invoice i
join FirstDate fd on fd.rn = 1
)
update UpdatedDate set IssuedDate = NewDate;
select * from Invoice;
输出:
| INVOICEID | STORECUSTOMERID | ISSUEDDATE | AMOUNT | ISPENALTY | EMPLOYEEID |
--------------------------------------------------------------------------------------------------
| 1 | 13 | January, 12 2007 08:00:00-0800 | 244 | 0 | 41 |
| 2 | 31 | January, 13 2007 08:00:00-0800 | 81 | 0 | 34 |
| 3 | 23 | January, 14 2007 08:00:00-0800 | 184 | 0 | 46 |
| 4 | 28 | January, 15 2007 08:00:00-0800 | 231 | 0 | 17 |
| 5 | 36 | January, 16 2007 08:00:00-0800 | 121 | 0 | 22 |
| 6 | 28 | January, 17 2007 08:00:00-0800 | 240 | 0 | 17 |
| 7 | 15 | January, 18 2007 08:00:00-0800 | 193 | 0 | 47 |
| 8 | 21 | January, 19 2007 08:00:00-0800 | 172 | 0 | 4 |
答案 4 :(得分:1)
根据OP的更新问题回答:http://sqlfiddle.com/#!3/dba13/22
with SeqInvoice as
(
select *, row_number() over(order by InvoiceId) rn from invoice
)
,SeqDate as
(
select *, row_number() over(order by IssuedDate) rn from invoice
)
update SeqInvoice set IssuedDate = sd.IssuedDate
from SeqDate sd
where sd.rn = SeqInvoice.rn;
select * from Invoice;
输出:
| INVOICEID | STORECUSTOMERID | ISSUEDDATE | AMOUNT | ISPENALTY | EMPLOYEEID |
----------------------------------------------------------------------------------------------------
| 1 | 13 | September, 19 2006 02:00:00-0700 | 244 | 0 | 41 |
| 2 | 31 | October, 24 2006 02:00:00-0700 | 81 | 0 | 34 |
| 3 | 23 | December, 11 2006 01:00:00-0800 | 184 | 0 | 46 |
| 4 | 28 | January, 09 2007 01:00:00-0800 | 231 | 0 | 17 |
| 5 | 36 | January, 12 2007 01:00:00-0800 | 121 | 0 | 22 |
| 6 | 28 | January, 15 2007 01:00:00-0800 | 240 | 0 | 17 |
| 7 | 15 | April, 05 2007 02:00:00-0700 | 193 | 0 | 47 |
| 8 | 21 | November, 21 2007 01:00:00-0800 | 172 | 0 | 4 |
<强>更新强>
这是一种不直接更新CTE的方法,直接更新基表:http://sqlfiddle.com/#!3/dba13/24
with SeqInvoice as
(
select *, row_number() over(order by InvoiceId) rn from invoice
)
,SeqDate as
(
select *, row_number() over(order by IssuedDate) rn from invoice
)
update I set IssuedDate = sd.IssuedDate
from Invoice i
join SeqInvoice si on si.InvoiceId = i.InvoiceId
join SeqDate sd on sd.rn = si.rn;
select * from Invoice;
答案 5 :(得分:0)
我会使用SQL游标,就像这样......
DECLARE @InvoiceId AS INT
DECLARE @PreviousInvoiceId AS INT
DECLARE @NextIssuedDate AS DATE
SET @PreviousInvoiceId = 0
--Date you want to start from
SET @NextIssuedDate = '2007-01-12'
DECLARE csrUpdateDate CURSOR FOR
SELECT InvoiceID FROM Invoice
ORDER BY InvoiceID
OPEN csrUpdateDate
FETCH NEXT FROM csrUpdateDate
INTO @InvoiceId
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN
IF(@InvoiceId <> @PreviousInvoiceId)
UPDATE Invoice
SET IssuedDate = @NextIssuedDate
WHERE InvoiceId = @InvoiceId
END
SET @PreviousInvoiceId = @InvoiceId
SET @NextIssuedDate = DATEADD(DAY,1,@NextIssuedDate)
FETCH NEXT FROM csrUpdateDate
INTO @InvoiceId
END
CLOSE csrUpdateDate
DEALLOCATE csrUpdateDate