使用sql将一个表转换为另一个表

时间:2017-10-17 16:09:25

标签: sql-server sql-server-2008 tsql

我有以下表1,我想将其转换为表2.该表包含一系列属性和日期。有些记录有审核日期,有些可能没有。我想返回一个属性列表和所有相应的审核日期,并且应该始终在审核日期中显示一个空值的记录。最后,我想在最后一列中返回上一个审核日期,这是该属性其他记录的最新审核日期。请告知如何以有效的方式进行转换。谢谢。

CREATE TABLE Table1
(`Property` varchar(1), `ReviewDate` varchar(9), `Due` datetime)
 ;

INSERT INTO Table1
(`Property`, `ReviewDate`, `Due`)
 VALUES
('A', '1/31/2017', '2017-03-30 19:00:00'),
('A', '1/15/2016', '2016-03-30 19:00:00'),
('A', '1/10/2015', '2015-03-30 19:00:00'),
('B', NULL, '2017-03-30 19:00:00'),
('B', '1/15/2016', '2016-03-30 19:00:00'),
('B', '1/10/2015', '2015-03-30 19:00:00')
;




CREATE TABLE Table2
(`Property` varchar(1), `ReviewDate` varchar(9), `Due` datetime, `PreviousReviewDate` varchar(9))
;

INSERT INTO Table2
(`Property`, `ReviewDate`, `Due`, `PreviousReviewDate`)
VALUES
('A', NULL, NULL, '1/31/2017'),
('A', '1/31/2017', '2017-03-30 19:00:00', '1/15/2016'),
('A', '1/15/2016', '2016-03-30 19:00:00', '1/10/2015'),
('A', '1/10/2015', '2015-03-30 19:00:00', NULL),
('B', NULL, '2017-03-30 19:00:00', '1/15/2016'),
('B', '1/15/2016', '2016-03-30 19:00:00', '1/10/2015'),
('B', '1/10/2015', '2015-03-30 19:00:00', NULL)
;

2 个答案:

答案 0 :(得分:1)

检查出来(SQL Fiddle):

CREATE TABLE Table1
(Property varchar(1), ReviewDate date, Due datetime);

INSERT INTO Table1
(Property, ReviewDate, Due)
VALUES
('A', '1/31/2017', '2017-03-30 19:00:00'),
('A', '1/15/2016', '2016-03-30 19:00:00'),
('A', '1/10/2015', '2015-03-30 19:00:00'),
('B', NULL, '2017-03-30 19:00:00'),
('B', '1/15/2016', '2016-03-30 19:00:00'),
('B', '1/10/2015', '2015-03-30 19:00:00');

CREATE TABLE Table2
(Property varchar(1), ReviewDate date, Due datetime, PreviousReviewDate date);

INSERT INTO Table2 (Property, ReviewDate, Due, PreviousReviewDate)
SELECT TOP 1 WITH TIES COALESCE(Curr.Property, Prev.Property), Curr.ReviewDate, Curr.Due, Prev.ReviewDate AS PreviousReviewDate 
FROM Table1 AS Curr
FULL JOIN Table1 AS Prev
ON Curr.Property = Prev.Property
AND Prev.ReviewDate < COALESCE(Curr.ReviewDate, GETDATE())
ORDER BY ROW_NUMBER() OVER (PARTITION BY Curr.Property, Curr.ReviewDate, Curr.Due ORDER BY Prev.ReviewDate DESC)

自己加入表格Property = Property and Date&lt;获取每个日期的所有先前日期的日期。然后,选择顶行,按上一个日期排序,以便最高结果是最新日期。您还必须为ReviewDate处理空值(我假设缺少日期可以作为当前日期处理)。

此外,我建议您使用date类型代替varchar这些日期字段。

答案 1 :(得分:0)

自动加入+不等式加入+分组。

使用相同的Property加入每一行并选择Max(ReviewDate)(在当前之前)以确定之前的

此解决方案符合标准SQL(Postgres,SqlServer,...)

CREATE TABLE Table1
(Property varchar(1), ReviewDate date, Due datetime)
 ;

INSERT INTO Table1
(Property, ReviewDate, Due)
 VALUES
('A', '1/31/2017', '2017-03-30 19:00:00'),
('A', '1/15/2016', '2016-03-30 19:00:00'),
('A', '1/10/2015', '2015-03-30 19:00:00'),
('B', NULL, '2017-03-30 19:00:00'),
('B', '1/15/2016', '2016-03-30 19:00:00'),
('B', '1/10/2015', '2015-03-30 19:00:00')
;


Create Table2 as
Select
    coalesce(A.Property,B.Property) as Property,        
    A.ReviewDate,
    A.Due, 
    Max(B.ReviewDate) as PreviousReviewDate
From
   Table1 A
   full join Table1 B On
        A.Property   = B.Property and
        A.ReviewDate > B.ReviewDate 
group by
   A.Property,A.ReviewDate,A.Due,B.Property
having
   not(A.ReviewDate is null and  Max(B.ReviewDate) is null)