如何分配以前的日期?

时间:2018-01-28 07:39:35

标签: sql sql-server tsql

表A

+====+======+============+============+
| id | m_id |    s_dt    |    e_dt    |
+====+======+============+============+
|  2 |  101 | 2015-06-28 | 2059-12-31 |
+----+------+------------+------------+
| 10 |  101 | 2018-01-07 | 2059-12-31 |
+----+------+------------+------------+

id = 2时,我想指定e_dt = 2018-01-06(即st_dt id=10前一天)。

我该怎么做?

3 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server 2012或更高版本,则可以尝试:

$ docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS                      PORTS                     NAMES
cee860adf641        ubuntu                             "tail -f /dev/null"      5 seconds ago       Up 3 seconds                                          ubuntu

答案 1 :(得分:0)

您需要按序列顺序在一条记录中记录两条记录的信息,因此首先按顺序使用CTE和ROW_NUMBER进行准备,然后将结果与自身连接以按顺序排列下一条记录的记录:

with TA as
(select ROW_NUMBER() over(order by id) as rn,* from TableA)
select t1.id,t1.m_id,t1.s_dt,DATEADD(day, -1,t2.st_dt) as e_dt 
from TA t1 join TA t2 on t1.rn+1=t2.rn

答案 2 :(得分:0)

为此,我建议使用Common Table Expression,例如:

--use common table expression to sort the m_id and id into unique row numbers
;WITH cte
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY m_id, id) AS rowNum
    , *
    FROM TableA
    )
--Update the original table, using the row number + 1 
--(use the next row to determine the next s_dt) 
UPDATE tblA
SET tblA.e_dt = DATEADD(day, - 1, tblB.s_dt)
FROM cte tblA
INNER JOIN cte tblB ON tblA.rowNum + 1 = tblB.rowNum and tblA.m_id = tblB.m_id

在我的示例中,您会看到e_dt在相应的m_id的最后一行/最后一行时,将是您的未来日期2059-12-31,因为没有行还有相应的s_dt。基于列的命名方式,基本上我所说的是“当前运行此m_id没有”结束日期“尚未 ...它仍在运行”。< / p>

此外,您将看到即使数据以非连续顺序插入表中,这仍然有效。这意味着,可以在另一个m_id的一对开始日期和结束日期之间插入具有不同值的m_id

测试结果:

enter image description here

我以前使用其他测试值进行测试的代码:

CREATE TABLE [dbo].[TableA](
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [m_id] [INT],
    [s_dt] [DATETIME],
    [e_dt] [DATETIME]
 CONSTRAINT [PK_TableA_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
) ON [PRIMARY]
GO


INSERT INTO [dbo].[TableA]
SELECT '101','2015-06-28','2059-12-31' UNION ALL
SELECT '101','2018-01-07','2059-12-31' UNION ALL
SELECT '102','2015-06-28','2059-12-31' UNION ALL
SELECT '102','2016-05-07','2059-12-31' UNION ALL
SELECT '103','2015-06-28','2059-12-31' UNION ALL
SELECT '103','2017-01-07','2059-12-31' UNION ALL
SELECT '102','2017-05-28','2059-12-31' UNION ALL
SELECT '104','2018-01-07','2059-12-31' UNION ALL
SELECT '103','2018-01-07','2059-12-31' UNION ALL
SELECT '102','2018-06-28','2059-12-31' UNION ALL
SELECT '104','2018-01-24','2059-12-31'
GO

--verify data
SELECT * FROM TableA

--use common table expression to sort the m_id and id into unique row numbers
;WITH cte
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY m_id, id) AS rowNum
    , *
    FROM TableA
    )
--Update the original table, using the row number + 1 (use the next row to determine the next s_dt) 
UPDATE tblA
SET tblA.e_dt = DATEADD(day, - 1, tblB.s_dt)
FROM cte tblA
INNER JOIN cte tblB ON tblA.rowNum + 1 = tblB.rowNum and tblA.m_id = tblB.m_id

--verify
SELECT * FROM TableA ORDER BY m_id, id


--DROP TABLE dbo.[TableA]