从复杂的select和内部连接语句更新表 - sql

时间:2012-05-16 22:16:01

标签: sql-server-2008 tsql

此代码适用于初始插入表格。但是现在我需要能够进行持续更新以将新行追加到表中...我是否需要为我要插入的每个项目执行SET。实际上,我已经尝试过这样做了,它仍然抱怨。

CREATE TABLE dbo.Calcs
(
    OutageDate DATE,
    StartTime TIME(7),
    EndTime TIME(7),
    Duration INT
);

INSERT dbo.Calcs SELECT '20101110', '16:00', '17:30', 90;


INSERT dbo.Calcs SELECT '20101111', '13:00', '14:02', 62;
INSERT dbo.Calcs SELECT '20101112', '17:00', '18:00', 60;
INSERT dbo.Calcs SELECT '20101113', '16:05', '16:25', 20;
INSERT dbo.Calcs SELECT '20101114', '16:59', '18:01', 62;
INSERT dbo.Calcs SELECT '20101115', '22:15', '01:30', 165;

CREATE TABLE dbo.TableIWantUpdated
(
    OutageDate DATE,
    StartHour TIME(7),
    StartMinutes TIME(7),
    StartTime TIME(7),
    EndHour int,
    EndMinutes int,
    EndTime TIME(7),
    Duration INT
);

;WITH n(n) AS 
(
  SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.objects
),
x AS
(
  SELECT 
    o.OutageDate, StartHour = (DATEPART(HOUR, StartTime) + n.n - 1) % 24,
    StartTime, EndTime, Duration,
    rn = ROW_NUMBER() OVER (PARTITION BY o.OutageDate, o.StartTime ORDER BY n.n)
  FROM n INNER JOIN dbo.Calcs AS o
  ON n.n <= CEILING(DATEDIFF(MINUTE, CONVERT(DATETIME, StartTime), 
    DATEADD(DAY, CASE WHEN EndTime < StartTime THEN 1 ELSE 0 END, 
    CONVERT(DATETIME, EndTime)))/60.0)
 ),
 mx AS (SELECT OutageDate, StartTime, minrn = MIN(rn), maxrn = MAX(rn) 
   FROM x GROUP BY OutageDate, StartTime)

 -- I want to use the below inner join from the CTE to update a table now
 UPDATE [dbo].[TableIWantUpdated]
 SELECT 
x.OutageDate, 
    x.StartHour, 
    StartMinutes = CASE 
      WHEN x.rn = mx.minrn THEN DATEPART(MINUTE, x.StartTime) ELSE 0 END,
    EndHour = x.StartHour + 1, 
    EndMinutes = CASE
      WHEN x.rn = mx.maxrn THEN DATEPART(MINUTE, x.EndTime) ELSE 0 END,
    x.StartTime, 
    x.EndTime,
    x.Duration
    --this is where I did the initial insert of data...but now I want it to be able to update
    --INTO [dbo].[TableIWantUpdated] FROM x INNER JOIN mx
 FROM x INNER JOIN mx 
 ON x.OutageDate = mx.OutageDate
 AND x.StartTime = mx.StartTime
 ORDER BY x.OutageDate, x.rn;
GO

1 个答案:

答案 0 :(得分:2)

那么

INSERT INTO应该有效。我也删除了底部的ORDER BY

;WITH n(n) AS 
(
  SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.objects
),
x AS
(
  SELECT 
    o.OutageDate, StartHour = (DATEPART(HOUR, StartTime) + n.n - 1) % 24,
    StartTime, EndTime, Duration,
    rn = ROW_NUMBER() OVER (PARTITION BY o.OutageDate, o.StartTime ORDER BY n.n)
  FROM n INNER JOIN dbo.Calcs AS o
  ON n.n <= CEILING(DATEDIFF(MINUTE, CONVERT(DATETIME, StartTime), 
    DATEADD(DAY, CASE WHEN EndTime < StartTime THEN 1 ELSE 0 END, 
    CONVERT(DATETIME, EndTime)))/60.0)
 ),
 mx AS (SELECT OutageDate, StartTime, minrn = MIN(rn), maxrn = MAX(rn) 
   FROM x GROUP BY OutageDate, StartTime)

 -- I want to use the below inner join from the CTE to update a table now
 INSERT INTO [dbo].[TableIWantUpdated]
 SELECT 
x.OutageDate, 
    x.StartHour, 
    StartMinutes = CASE 
      WHEN x.rn = mx.minrn THEN DATEPART(MINUTE, x.StartTime) ELSE 0 END,
    EndHour = x.StartHour + 1, 
    EndMinutes = CASE
      WHEN x.rn = mx.maxrn THEN DATEPART(MINUTE, x.EndTime) ELSE 0 END,
    x.StartTime, 
    x.EndTime,
    x.Duration
    --this is where I did the initial insert of data...but now I want it to be able to update
    --INTO [dbo].[TableIWantUpdated] FROM x INNER JOIN mx
 FROM x INNER JOIN mx 
 ON x.OutageDate = mx.OutageDate
 AND x.StartTime = mx.StartTime
 --ORDER BY x.OutageDate, x.rn;
GO