Tsql ivotedWithLastValue,其中val LastVal或LastVal为NULL 按Id订购,beginT
在这个查询中,我使用了LAG()函数来获取每个字段的最后一个值。根据此值,您可以在最终查询中筛选出未更改的记录,如上所示。据我所知,我必须创建两个临时表,并通过筛选将它们合并Tsql ivotedWithLastValue,其中val LastVal或LastVal为NULL 按Id订购,beginT,tsql,sql-server-2014,unpivot,cdc,Tsql,Sql Server 2014,Unpivot,Cdc,在这个查询中,我使用了LAG()函数来获取每个字段的最后一个值。根据此值,您可以在最终查询中筛选出未更改的记录,如上所示。据我所知,我必须创建两个临时表,并通过筛选将它们合并a.id=b.id和a.field=b.field和a.rn=b.rn-1和a.valueb.value。我说的对吗?您不需要创建任何临时表;您只需参考两次CTE(历史2)。看看建议的查询。您的示例返回了几个错误:关键字“with.”附近的语法不正确。和附近的语法不正确,“我也不理解历史中的查询2。据我所知,unpivot应
a.id=b.id和a.field=b.field和a.rn=b.rn-1和a.valueb.value
。我说的对吗?您不需要创建任何临时表;您只需参考两次CTE(历史2)。看看建议的查询。您的示例返回了几个错误:关键字“with.”附近的语法不正确。
和附近的语法不正确,“
我也不理解历史中的查询2。据我所知,unpivot
应用于结果表,但在历史记录2中没有任何表。没有测试查询,因为我没有您的表的示例。。。我现在已经纠正了错误;尝试执行已更改的查询。History2 CTE只是原始查询的副本,并添加了一些列(id,rn)。谢谢。查询工作正常,但不正常。我更新一个字段2次,另一个字段1次。查询不返回上次更新的上次结果,但显示上次endT
…如果在中使用历史记录作为(
使用其中cz.id='some id'
。在这种情况下,结果是LastVal
С对应于实际值。但是如果其中包含多个id或其中不存在则LastVal
的值是混合的。您使用cz.id列的目的是什么?如果没有数据样本,这很难回答。对不起。请看。我补充了我的问题。啊哈-我明白了。我简化了我的查询有点太多:-)我现在在示例中添加了一个id列。您应该在LAG()中的PARTITION BY子句中添加cz.id语句。如果这不能解决问题,请告诉我。太好了!关于您的其他问题:如果我理解正确,那么可以创建一个存储过程来输出多个表的更改。它可能需要一点动态SQL,并且可能会变得更复杂,具体取决于您的具体要求。
with History AS (
SELECT
cz.GUID as Id,
cz.category,
isnull(cz.area, 0) as area,
isnull(cz.oilwidthmin,0) as oilwidthmin,
isnull(cz.oilwidthmax,0) as oilwidthmax,
isnull(cz.efectivwidthmin,0) as efectivwidthmin,
isnull(cz.efectivwidthmax,0) as efectivwidthmax,
isnull(cz.koafporistmin,0) as koafporistmin,
isnull(cz.koafporistmax,0) as koafporistmax,
CASE cz.__$operation
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END operation,
map.tran_begin_time as beginT,
map.tran_end_time as endT
FROM cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all') AS cz
INNER JOIN [cdc].[lsn_time_mapping] map
ON cz.[__$start_lsn] = map.start_lsn
)
SELECT field, val, operation, beginT, endT FROM History
unpivot ( [val] for field in
(
--category,
area,
oilwidthmin,
oilwidthmax,
efectivwidthmin,
efectivwidthmax,
koafporistmin,
koafporistmax))t where id = '2D166098-7CBD-4622-9EB0-000070506FE6'
WITH History AS (
SELECT
*,
CASE cz.__$operation
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END operation,
map.tran_begin_time as beginT,
map.tran_end_time as endT
FROM cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all') AS cz
INNER JOIN [cdc].[lsn_time_mapping] map
ON cz.[__$start_lsn] = map.start_lsn
where cz.GUID = '2D166098-7CBD-4622-9EB0-000070506FE6'
),
UnpivotedValues AS(
SELECT guid, field, val, operation, beginT, endT
FROM History
UNPIVOT ( [val] FOR field IN
(
area,
oilwidthmin,
oilwidthmax,
efectivwidthmin,
efectivwidthmax,
koafporistmin,
koafporistmax
))t
),
UnpivotedWithLastValue AS (
SELECT
*,
--Use LAG() to get the last value for the same field
LAG(val, 1) OVER (PARTITION BY field ORDER BY BeginT) LastVal
FROM UnpivotedValues
)
--Filter out record where the value equals the last value for the same field
SELECT * FROM UnpivotedWithLastValue WHERE val <> LastVal OR LastVal IS NULL ORDER BY guid
WITH
History AS
(
SELECT
cz.GUID as Id,
cz.category,
isnull(cz.area, 0) as area,
isnull(cz.oilwidthmin,0) as oilwidthmin,
isnull(cz.oilwidthmax,0) as oilwidthmax,
isnull(cz.efectivwidthmin,0) as efectivwidthmin,
isnull(cz.efectivwidthmax,0) as efectivwidthmax,
isnull(cz.koafporistmin,0) as koafporistmin,
isnull(cz.koafporistmax,0) as koafporistmax,
CASE
cz.__$operation
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END operation,
map.tran_begin_time as beginT,
map.tran_end_time as endT,
ROW_NUMBER() OVER (PARTITION BY cz.GUID ORDER BY map.tran_end_time ASC) as rn
FROM
cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all') AS cz
INNER JOIN
[cdc].[lsn_time_mapping] map ON cz.[__$start_lsn] = map.start_lsn
),
History2 AS
(
SELECT id, field, val, operation, beginT, endT, rn FROM History
unpivot ( [val] for field in
(
--category,
area,
oilwidthmin,
oilwidthmax,
efectivwidthmin,
efectivwidthmax,
koafporistmin,
koafporistmax))t
where id = '2D166098-7CBD-4622-9EB0-000070506FE6'
)
-- return the values that were inserted first
SELECT
a.*
FROM
History2 a
WHERE
a.rn=1
UNION ALL
-- ... and then return only the values that are different from the previous ones
SELECT
a.*
FROM
History2 a
INNER JOIN
History2 b ON a.id = b.id AND a.field=b.field AND a.rn = b.rn-1 AND a.value<>b.value
WHERE
a.rn>1
WITH History AS (
SELECT
*,
CASE cz.__$operation
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END operation,
map.tran_begin_time as beginT,
map.tran_end_time as endT
FROM cdc.fn_cdc_get_all_changes_Dbo_YourTable(sys.fn_cdc_get_min_lsn('Dbo_YourTable'), sys.fn_cdc_get_max_lsn(), 'all') AS cz
INNER JOIN [cdc].[lsn_time_mapping] map
ON cz.[__$start_lsn] = map.start_lsn
),
UnpivotedValues AS(
SELECT id, field, val, operation, beginT, endT, t.tran_id
FROM History
UNPIVOT ( [val] FOR field IN
(Column1, Column2, Column3))t
),
UnpivotedWithLastValue AS (
SELECT
*,
--Use LAG() to get the last value for the same field
LAG(val, 1) OVER (PARTITION BY id, field ORDER BY BeginT) LastVal
FROM UnpivotedValues
)
--Filter out record where the value equals the last value for the same field
SELECT * FROM UnpivotedWithLastValue WHERE val <> LastVal OR LastVal IS NULL
ORDER BY Id, beginT