在视图中计算的两列虚拟列

huangapple go评论52阅读模式
英文:

Two virtually calculated columns in view

问题

以下是已翻译的内容:

Initially in a regular table, there are two columns Key and ParentKey. The Key gets its value as an identity column - automatically. ParentKey - by the expression

一开始,在一个常规表中,有两列 KeyParentKeyKey 列会自动获得一个身份列的值。ParentKey 列的值则由以下表达式确定:

WITH
  latest
  as
(
  SELECT
   ProductID,
   Date,
   [Key],
    ROW_NUMBER() OVER (
      PARTITION BY  ProductID
          ORDER BY [Date] DESC -- 按最新日期排序
    ) rn 
  FROM
   [MyTable]
)


UPDATE      
  u 
SET
  u.[ParentKey] = latest.[Key] 
FROM
   [MyTable] u
INNER JOIN
  latest
    ON u.ProductID = latest.ProductID
WHERE
  latest.rn = 1

Does it possible to combine both of these two steps simultaneously when creating the View (Key and ParentKey becomes virtual)? I have a solution for the first part of these task - creating Key column in a view. Could it be combined with the step which then sets ParentKey?

是否可以在创建视图时同时合并这两个步骤,使KeyParentKey成为虚拟列?我已经有了解决方案,可以在视图中创建Key列。是否可以将其与设置ParentKey的步骤合并?

Current Code

当前的代码如下:

CREATE VIEW v_Test 

AS
SELECT
ProductID
,Date,
CAST (ROW_NUMBER() OVER( ORDER BY [ProductID] ) AS int) as [Key]

-- some expression for ParentKey?

FROM [MyTable]

Desired View output (Key and ParentKey must be processed during view creation)

期望的视图输出如下(KeyParentKey 必须在视图创建过程中处理):

+-------------------------------------------------
|ProductID  |   Date        |  Key   |  ParentKey 
+-------------------------------------------------
|111        |   2017-12-31  |   1    |   3
|111        |   2018-12-31  |   2    |   3
|111        |   2019-12-31  |   3    |   3
|222        |   2017-12-31  |   4    |   6
|222        |   2018-12-31  |   5    |   6
|222        |   2019-12-31  |   6    |   6
|333        |   2017-12-31  |   7    |   9
|333        |   2018-12-31  |   8    |   9
|333        |   2019-12-31  |   9    |   9
英文:

Initially in a regular table, there are two columns Key and ParentKey. The Key gets its value as an identity column - automatically. ParentKey - by the expression

 WITH
  latest
  as
(
  SELECT
   ProductID,
   Date,
   [Key],
    ROW_NUMBER() OVER (
      PARTITION BY  ProductID
          ORDER BY [Date] DESC -- order by latest Date
    ) rn 
  FROM
   [MyTable]
)


UPDATE      
  u 
SET
  u.[ParentKey] = latest.[Key] 
FROM
   [MyTable] u
INNER JOIN
  latest
    ON u.ProductID = latest.ProductID
WHERE
  latest.rn = 1

Does it possible to combine both of these two steps simultaneously when creating the View (Key and ParentKey becomes virtual)? I have a solution for the first part of these task - creating Key column in a view. Could it be combined with the step which then sets ParentKey?

Current Code

CREATE VIEW v_Test 

AS
SELECT
ProductID
,Date,
CAST (ROW_NUMBER() OVER( ORDER BY [ProductID] ) AS int) as [Key]

-- some expression for ParentKey?

FROM [MyTable]

Desired View output (Key and ParentKey must be processed during view creation)

+-------------------------------------------------
|ProductID  |   Date        |  Key   |  ParentKey 
+-------------------------------------------------
|111        |   2017-12-31  |   1    |   3
|111        |   2018-12-31  |   2    |   3
|111        |   2019-12-31  |   3    |   3
|222        |   2017-12-31  |   4    |   6
|222        |   2018-12-31  |   5    |   6
|222        |   2019-12-31  |   6    |   6
|333        |   2017-12-31  |   7    |   9
|333        |   2018-12-31  |   8    |   9
|333        |   2019-12-31  |   9    |   9

答案1

得分: 2

如果我正确理解你想要做的,那么你可以将带有行号的查询放入一个CTE或派生表中,然后在窗口聚合中引用它以获取最大值。

CREATE VIEW v_Test
AS
  WITH T
       AS (SELECT ProductID,
                  Date,
                  ROW_NUMBER() OVER(ORDER BY [ProductID] ASC,  [Date] ASC ) AS [Key]
           FROM   [MyTable])
  SELECT ProductID,
         Date,
         [Key],
         MAX([Key]) OVER (PARTITION BY [ProductID]) AS [ParentKey]
  FROM   T 

这些“Keys”随时间变化可能会不太稳定,因为它们在为不相关的产品插入后可能会发生变化。

英文:

If I have understood what you are trying to do correctly then you can put the query with the row number in a CTE or derived table and then reference that in a windowed aggregate to get the max.

CREATE VIEW v_Test
AS
  WITH T
       AS (SELECT ProductID,
                  Date,
                  ROW_NUMBER() OVER(ORDER BY [ProductID] ASC,  [Date] ASC ) AS [Key]
           FROM   [MyTable])
  SELECT ProductID,
         Date,
         [Key],
         MAX([Key]) OVER (PARTITION BY [ProductID]) AS [ParentKey]
  FROM   T 

These "Keys" will not be at all stable over time though as they can change after inserts for unrelated products.

答案2

得分: 0

如果我理解你的意思正确,我相信只使用MAX和OVER子句将更简短。类似于

UPDATE u
SET u.[ParentKey] =
FROM [MyTable] u
CROSS APPLY (
    SELECT MAX([Key] OVER (PARTITION BY ProductID ORDER BY [DATE] DESC) LatestKey) ca
英文:

If I understand you correctly, I believe will be much shorter using only MAX with OVER clause. Something like

UPDATE      
  u 
SET
  u.[ParentKey] = 
FROM
   [MyTable] u
CROSS APPLY (SELECT MAX( [Key] OVER ( PARTITION BY ProductID ORDER BY [DATE] DESC ) LatestKey ) ca 

huangapple
  • 本文由 发表于 2023年2月14日 19:12:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定