如何在 SQL SERVER 2017 SSMS 中用之前保存的行值替换行值

How to replace row value with previous saved row value in SQL SERVER 2017 SSMS

首先我的问题太复杂了,抱歉我的英语不好

所以,我在 SQL 中得到了一些 Table-Valued Function 查询,以便在 VB[=18= 上 select 的每一天自动生成 5 行]

这里有一些示例 Table-Valued Function 如何在 2 天内工作

每次列数量的默认值为 1

默认名称始终为 A、B、C、D、E

它将每天生成新的 5 行,然后来自上面的所有数据将使用存储过程 (tblProduce) 提交到另一个 table 图片中的所有列都来自 VB DataViewGrid,我只创建 Table-Valued Function 来获取 ID、Name。剩下的会在VB

上补上

主要问题:

我想要的是,如果我在 2019 年 7 月 25 日创建并保存此数据,并且我将 CheckBox 的其中一个行值更改为 True

然后,第二天,当我要创建另一个数据时,应该是这样的 这是预期的数据应该在第二天

绿色背景表示当复选框 = True 时数据取自上次保存的行

这是用于 SSMS SQL Server 2017,我已经尝试在 Table Valued Function 上使用 UNION / SUB QUERY 但仍然没有弄清楚如何做这件事

QUERY 用于获取 selected 的天数:

CREATE FUNCTION [dbo].[tvfCustomDateRange] (@Increment char(1), @StartDate date, @EndDate date) 
RETURNS @SelectedRange TABLE (cDate date) 
AS
BEGIN 

      ;WITH cteRange (DateRange) AS (
            SELECT @StartDate
            UNION ALL
            SELECT 
                  CASE
                        WHEN @Increment = 'd' THEN DATEADD(dd, 1, DateRange)
                        WHEN @Increment = 'w' THEN DATEADD(ww, 1, DateRange)
                        WHEN @Increment = 'm' THEN DATEADD(mm, 1, DateRange)
                  END
            FROM cteRange
            WHERE DateRange <= 
                  CASE
                        WHEN @Increment = 'd' THEN DATEADD(dd, -1, @EndDate)
                        WHEN @Increment = 'w' THEN DATEADD(ww, -1, @EndDate)
                        WHEN @Increment = 'm' THEN DATEADD(mm, -1, @EndDate)
                  END)

      INSERT INTO @SelectedRange (cDate)
      SELECT DateRange
      FROM cteRange
      OPTION (MAXRECURSION 3660);
      RETURN
END

我在 vb 上 select 每隔多少天生成第 5 行的查询是:

CREATE FUNCTION [dbo].[tvfGenerate5Row] (@BeginDate DateTimeOffset, @EndDate Datetimeoffset)
RETURNS TABLE 
AS
RETURN 
(
    SELECT IsNuLL(tblProduce.Idtbl5Row,tblCustom.Idtbl5Row),
           IsNULL(tblProduce.Name,tblCustom.Name),
           IsNULL(tblProduce.Quantity,1),
           IsNULL(tblProduce.cDate,tblCustom.cDate),
           IsNULL(tblProduce.CheckBox,'')

    FROM  (SELECT Name, cDate, Idtbl5Row
           FROM tvfCustomDateRange('d', @BeginDate, @EndDate) CROSS JOIN tblWith5Row) AS tblCustom LEFT OUTER JOIN tblProduce ON tblCustom.cDate=tblProduce.cDate
)
CREATE TABLE tblProduce
(
    IdtblProduce  BigInt Primary Key,
    Idtbl5Row     BigInt,
    Name          VarChar(25),
    Quantity      Integer,
    cDate         DateTime,
    CheckBox      Bit,
    FOREIGN KEY (Idtbl5Row) REFERENCES tblWith5Row(Idtbl5Row)
)

因为您的 table 中已经有这 5 行。现在每次你只想输入与新日期相同的条目时,所以最好使用以前的日期数据并将 select 与你的新日期数据一起使用。

生成 5 个日期的函数:-

    CREATE FUNCTION [dbo].[tvfCustomDateRange] (@Increment char(1), @StartDate date, @EndDate date) 
    RETURNS @SelectedRange TABLE (cDate date) 
    AS
    BEGIN 

          ;WITH cteRange (DateRange) AS (
                SELECT @StartDate
                UNION ALL
                SELECT 
                      CASE
                            WHEN @Increment = 'd' THEN DATEADD(dd, 1, DateRange)
                            WHEN @Increment = 'w' THEN DATEADD(ww, 1, DateRange)
                            WHEN @Increment = 'm' THEN DATEADD(mm, 1, DateRange)
                      END
                FROM cteRange
                WHERE DateRange <= 
                      CASE
                            WHEN @Increment = 'd' THEN DATEADD(dd, -1, @EndDate)
                            WHEN @Increment = 'w' THEN DATEADD(ww, -1, @EndDate)
                            WHEN @Increment = 'm' THEN DATEADD(mm, -1, @EndDate)
                      END)

          INSERT INTO @SelectedRange (cDate)
          SELECT DateRange
          FROM cteRange
          OPTION (MAXRECURSION 3660);
          RETURN
    END


    CREATE FUNCTION [dbo].[tvfGenerate5Row] (@BeginDate DateTimeOffset, @EndDate Datetimeoffset)
    RETURNS TABLE 
    AS
    RETURN 
    (
        SELECT tblCustom.Name,tblCustom.cDate, tblCustom.ID, 0   AS CHECKBOX
        FROM  (SELECT cDate, Name, ID
               FROM tvfCustomDateRange('d', @BeginDate, @EndDate) CROSS JOIN tableWith5Row) AS tblCustom 
    )

并得到你的输出结果:

    ; WITH CTE AS (
    select ID, MAX(CDATE) AS CDATE from dbo.tvfGenerate5Row( '2019-08-13', '2019-08-15' ) GROUP BY ID 
    )
    SELECT CTE.ID, CTE.CDATE , CASE WHEN D.QUANTITY=1 THEN 1 ELSE 0 END AS CC FROM CTE 
    CROSS APPLY (
           SELECT ID, MAX(QUANTITY) AS QUANTITY 
           FROM tblProduce AS TP 
           WHERE CTE.ID=TP.Idtbl5Row 
           AND QUANTITY = 1
    ) AS D

对于您在评论中提到的案例,我们认为您已经有回溯日期的条目。因此,获得预期结果所需的查询将是:

    ; WITH CTE AS (
    select ID, MAX(CDATE) AS CDATE from dbo.tvfGenerate5Row( '2019-08-13', '2019-08-15' ) GROUP BY ID )
    , CT AS (
    SELECT CTE.ID,  CTE.CDATE  , CASE WHEN D.QUANTITY=1 THEN 1 ELSE 0 END AS CC FROM CTE 
    CROSS APPLY (SELECT ID, MAX(QUANTITY) AS QUANTITY  FROM tblProduce AS TP WHERE CTE.ID=TP.Idtbl5Row and QUANTITY=1  ) AS D
    ) 
    SELECT CT.ID, 
    CASE WHEN tblProduce.CHECKBOX = 1 THEN tblProduce.CDATE ELSE CT.CDATE END AS CDATE, 
    CASE WHEN tblProduce.CHECKBOX = 1 THEN tblProduce.QUANTITY ELSE 1 END AS QUANTITY 
    FROM CT LEFT JOIN ( SELECT * FROM tblProduce WHERE CHECKBOX=1 ) tblProduce ON CT.ID=tblProduce.Idtbl5Row