【问题标题】:Creating rows in a SELECT based on INT from another table根据另一个表中的 INT 在 SELECT 中创建行
【发布时间】:2020-05-06 09:13:44
【问题描述】:

假设我有一个名为“contracts”的表,其中有一列“NumYears”。

例如。

SELECT 
    ClientId,
    NumYears
FROM Contracts

ClientId NumYears
-------- -----------
123456789    5
987654321    3

我有另一个表 'contract_reviews' 可以通过 ClientId 加入合同。

每年都会要求用户查看存档的信息,并在完成后在“contract_reviews”中插入一个新行

SELECT
    ClientId,
    Reviewed,
    YearFor,
    OtherColumn
FROM Contract_Reviews

ClientId  Reviewed    YearFor OtherColumn
--------- ----------- ------- -----------
123456789 1           2018    '£100'
123456789 1           2019    '£100'

客户 '123456789' 可能在第二年,所以 'contract_reviews' 将只保存 2 条记录。到“NumYears”结束时,我们应该期待 5。

基本上,我需要从“contract_reviews”中选择所有行,并为缺失的“contract_reviews”生成新的空行,直到“NumYears”计数

ClientId  Reviewed    YearFor OtherColumn
--------- ----------- ------- -----------
123456789 1           2018    '£100'
123456789 1           2019    '£100'
123456789 0           NULL    NULL
123456789 0           NULL    NULL
123456789 0           NULL    NULL

这个问题Duplicated rows (x) amount of times in a table提供了一些帮助,但解决方案仍然在逃避我。

【问题讨论】:

  • 如果给定合同的审查表中还没有行怎么办?
  • 好问题!我没有考虑过,谢谢。我认为出于报告目的,它应该返回 X (NumYears) 的空白行,因为如果没有记录是我们失败的,因为应该在创建合同时插入第一条记录。

标签: sql sql-server tsql sql-server-2008 recursive-query


【解决方案1】:

一种选择是使用递归查询:

with cte as (
    select 
        c.clientId, 
        c.numYears - (
            select count(*) from contract_reviews cr where cr.clientId = c.clientId
        ) numYears
    from contracts c
    union all
    select clientId, numYears - 1 from cte where numYears > 1
)
insert into contract_reviews(clientId) 
select clientId from cte

递归 cte 的锚计算每个客户的评论表中“缺失”了多少行,然后递归部分生成它们。最后,外部查询执行插入操作。

Demo on DB Fiddle - 一旦执行查询,review 表的内容为:

客户 ID |评论 |年份为 |其他列 :-------- | :------- | :-------- | :---------- 123456789 | 1 | 2018 | 100 英镑 123456789 | 1 | 2019 | 100 英镑 123456789 | | | 123456789 | | | 123456789 | | | 987654321 | | | 987654321 | | | 987654321 | | |

【讨论】:

    猜你喜欢
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2023-02-11
    • 2018-06-20
    • 2020-09-20
    相关资源
    最近更新 更多