sql-server 如何插入基于另一列值的值

xpszyzbs  于 2022-10-31  发布在  其他
关注(0)|答案(3)|浏览(191)

下面是我的表的一个子集(对于第一个id)
| 日期|标识符|价值|
| - -|- -|- -|
| 2022年1月1日|一个|五个|
| 2022年8月1日|一个|2个|
对于每个ID,日期不是连续的(例如,对于ID 1,最小日期是01/01/2022,最大日期是08/01/2022)--两个日期之间有7天。我希望插入行以使每个ID的日期连续--值字段/列的值将填充0,以便更新后的表如下所示:
| 日期|标识符|价值|
| - -|- -|- -|
| 2022年1月1日|一个|五个|
| 2022年2月1日|一个|第0页|
| 2022年3月1日|一个|第0页|
| 2022年4月1日|一个|第0页|
| 2022年5月1日|一个|第0页|
| 2022年6月1日|一个|第0页|
| 2022年7月1日|一个|第0页|
| 2022年8月1日|一个|2个|
任何关于如何实现这一点的SQL代码都将受到高度赞赏。我有一个日历表,但不确定如何将它与上面的表连接起来,以便我用0动态地为每个ID填充缺失的日期。
我的行事历表格如下所示:
| 日期|
| - -|
| 2022年1月1日|
| 2022年2月1日|
| 2022年3月1日|
| 2022年4月1日|

pkmbmrz7

pkmbmrz71#

考虑到你说你有一个日历表,看起来你需要做什么JOIN到它与MINMAX的日期从你的其他表,和LEFT JOIN回到你的表:

WITH MinMax AS(
    SELECT ID,
           MIN(date) AS MinDate,
           MAX(date) AS MaxDate
    FROM dbo.YourTable
    GROUP BY ID),
Dates AS(
    SELECT MM.ID,
           C.CalendarDate AS [Date]
    FROM MinMax MM
         JOIN dbo.CalendarTable C ON MM.MinDate <= C.CalendarDate
                                 AND MM.MaxDate >= C.CalendarDate)
SELECT D.ID,
       D.[Date],
       ISNULL(YT.[Value],0) AS [Value]
FROM Dates D
     LEFT JOIN dbo.YourTable YT ON D.ID = YT.ID
                               AND D.[Date] = YT.[Date];
o7jaxewo

o7jaxewo2#

SET DATEFORMAT DMY

-- CREATE A TABLE WITH OUR INPUT DATA
DROP TABLE IF EXISTS #TheData
GO
CREATE TABLE #TheData
(TheDate DATE, id INT, TheValue INT)
INSERT INTO #TheData
(TheDate,id,Thevalue)
VALUES
('01/01/2022',1,5),
('08/01/2022',1,2),
('17/01/2022',2,7),
('25/01/2022',2,7),
('15/02/2022',2,7)

-- CREATE A CALENDAR CTE

DECLARE @StartDate  date = '20210101';
DECLARE @CutoffDate date = DATEADD(DAY, -1, DATEADD(YEAR, 2, @StartDate));

;WITH DateSeq(TheDate) AS 
(
  SELECT @StartDate 
  UNION ALL 
  SELECT DATEADD(dd,1,TheDate) FROM DateSeq
  WHERE TheDate < @CutoffDate
)

-- CROSS JOIN OUR CALENDAR CTE TO OUR SOURCE DATA. DERIVED TABLE TO GET FIRST AND LAST OF EACH RANGE TO USE FOR JOIN
SELECT
ds.*
,SourceDataRangesByID.ID
,ISNULL(td.TheValue,0) AS TheValue
FROM
DateSeq ds
CROSS JOIN
(
    SELECT 
    d.ID
    ,MIN(d.TheDate) AS MinDatePerID
    ,MAX(d.TheDate) AS MaxDatePerID
    FROM #TheData d 
    GROUP BY d.ID
) SourceDataRangesByID 
LEFT JOIN #TheData td ON td.id = SourceDataRangesByID.ID AND td.TheDate = ds.TheDate
WHERE ds.TheDate >= SourceDataRangesByID.MinDatePerID
AND ds.TheDate <= SourceDataRangesByID.MaxDatePerID

OPTION (MAXRECURSION 0);
wwwo4jvm

wwwo4jvm3#

尝试generate_series创建一个日期表,然后将其与之右连接,并为非空值合并

SELECT generate_series('2016-01-01',  -- series start date
                           '2018-06-30',  -- series end date
                           '1 day'::interval)::date AS day) AS daily_series
   from mytable

See Generate_Series for TSQL

 https://dba.stackexchange.com/questions/255165/does-ms-sql-server-have-generate-series-function 

(Sql server 2022)

https://learn.microsoft.com/en-us/sql/t-sql/functions/generate-series-transact-sql?view=sql-server-ver16

相关问题