我如何将此数组映射转换转换为 SQL?

How would I translate this array mapping transformation to SQL?

假设我有以下几行:

const rows = [
  { contract: "HC003", type: "Regular" },
  { contract: "HC005", type: "NOT-Regular" },
  { contract: "HC006", type: "NOT-Regular" },
  { contract: "HC007", type: "NOT-Regular" },
  { contract: "HC008", type: "Regular" },
  { contract: "HC015", type: "NOT-Regular" },
  { contract: "HC016", type: "Regular" }
];

每一行都需要添加一个 group 列。此列获取 preceding 行的最后一行的 contract 值(这意味着顺序很重要),其中 type 等于 Regular .

在 JS 中,我会这样表达:

const findLastRegularContract = rangeEnd =>
  rows
    .slice(0, rangeEnd)
    .reverse()
    .find(row => row.type === "Regular");

const withGroups = rows.map((row, i) => ({
  ...row,
  group: findLastRegularContract(i + 1).contract
}));

这会导致以下结果:

[
  { contract: "HC003", type: "Regular", group: "HC003" },
  { contract: "HC005", type: "NOT-Regular", group: "HC003" },
  { contract: "HC006", type: "NOT-Regular", group: "HC003" },
  { contract: "HC007", type: "NOT-Regular", group: "HC003" },
  { contract: "HC008", type: "Regular", group: "HC008" },
  { contract: "HC015", type: "NOT-Regular", group: "HC008" },
  { contract: "HC016", type: "Regular", group: "HC016" }
]

如何在 SQL 查询中执行此数据转换? 有没有办法 "map" 遍历 SQL 中的行?或者是否有一种声明式/惯用的方式来实现相同的结果?

编辑:还有两个额外的列可以帮助保持适当的排序,即:

你可以尝试使用

 select  case 
          when contract =  "HC003" then  "Regular" 
          when contract =  "HC003" then  "NOT-Regular"
          when contract =  "HC006" then  "NOT-Regular" 
          when contract =  "HC007" then  "NOT-Regular"
          when contract =  "HC008" then  "Regular"
          when contract =  "HC015" then  "NOT-Regular" 
          when contract =  "HC016" then  "Regular"  
        end type          

     , case
          when contract =  "HC003" then  "HC003" 
          when contract =  "HC003" then  "HC003"
          when contract =  "HC006" then  "HC003" 
          when contract =  "HC007" then  "HC003"
          when contract =  "HC008" then  "HC008"
          when contract =  "HC015" then  "HC008" 
          when contract =  "HC016" then  "HC008"  
        end group  
from my_table  

或者您可以将值存储在 table 的相应列中并加入 ..

my_table

   id   contract    type        group 
   1    "HC003"   "Regular"       "HC003" 
   2    "HC005"   "NOT-Regular"   "HC003" 
   3    "HC006"   "NOT-Regular"   "HC003" 
   4    "HC007"   "NOT-Regular"   "HC003" 
   5    "HC008"   "Regular"       "HC008" 
   6    "HC015"   "NOT-Regular"   "HC008" 
   7    "HC016"   "Regular"       "HC016" 

原始问题的扩展是正确答案的关键,因为解决方案依赖于正确的行排序。

这可以以声明方式执行,例如以下查询(重命名了几列):

SELECT  
    a.contract_id, a.contract_type, a.valid_from, a.valid_to,   
    contract_group = 
        (SELECT TOP 1
            contract_id
        FROM 
            contracts b
        WHERE
             b.valid_from <= a.valid_from AND b.contract_type = "Regular"
        ORDER BY b.valid_from DESC)
FROM
    contracts a
ORDER BY
    a.valid_from ASC

希望对您有所帮助。