如何在 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
首先我的问题太复杂了,抱歉我的英语不好
所以,我在 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