4

目前,我有这个记录

发票清单表

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
4

6 回答 6

7

如果您知道序列中的第一个日期,您可以简单地将 RowNumber 添加到它:

; 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)

这是带有示例的 Sql Fiddle

更新

完全匹配第一个问题的输出

; 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))

并重新安排日期以遵循 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
于 2012-08-28T14:11:42.397 回答
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 。

于 2012-08-28T14:15:10.760 回答
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]

SQLFiddle 演示

于 2012-08-28T14:23:33.430 回答
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 |
于 2012-08-28T15:04:31.970 回答
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;
于 2012-08-28T15:14:16.973 回答
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 
于 2012-08-28T14:33:19.047 回答