在SQL中创建没有循环的年/季度表

时间:2019-02-07 19:13:40

标签: sql sql-server tsql

我有一个开始年和一个结束年,例如2017年和2019年。

我想创建一个表,其中包含我声明的startYear和endYear之间的列 year quarter (例如1、2、3、4),并具有 quarter ,最后一个 endYear 停在2(始终向前看)。

在下面采样所需的输出。

year    quarter
2017    1
2017    2
2017    3
2017    4
2018    1
2018    2
2018    3
2018    4
2019    1
2019    2

似乎应该很简单,除了依赖循环或UNION的笨拙方法,或者只是手动将值手动插入表之外,对我来说什么都没有发生。

4 个答案:

答案 0 :(得分:7)

还有另一种选择...与Cross Join配合使用的临时统计表

示例

Declare @Y1 int = 2017
Declare @Y2 int = 2019

Select *
 From ( Select Top (@Y2-@Y1+1) Year=@Y1-1+Row_Number() Over (Order By (Select NULL)) From master..spt_values n1 ) A
 Cross Join (values (1),(2),(3),(4)) B([Quarter])

返回

Year    Quarter
2017    1
2017    2
2017    3
2017    4
2018    1
2018    2
2018    3
2018    4
2019    1
2019    2
2019    3
2019    4

答案 1 :(得分:2)

使用递归CTE:

with yq as (
      select 2017 as yyyy, 1 as qq
      union all
      select (case when qq = 4 then yyyy + 1 else yyyy end), 
              (case when qq = 4 then 1 else qq + 1 end)
      from yq
      where yyyy < 2019 or yyyy = 2019 and qq < 2
     )
select *
from yq;

如果表中的行数超过100,则还需要option (maxrecursion 0)

Here是db <>小提琴。

答案 2 :(得分:2)

此解决方案与John的解决方案非常相似,但是它不依赖于系统表。

def load_json_file(self):
    if os.path.isfile(os.path.dirname(os.path.realpath(sys.argv[0])) + '\dwconfig.json'):
        with open('dwconfig.json') as json_data_file:
            cfg_data = json.load(json_data_file)
        return cfg_data

答案 3 :(得分:0)

让我为您提出一个递归查询:

WITH prepare AS
(
SELECT tbl.year
FROM (VALUES (2017) ) AS tbl(year)    -- for example, start year is 2k17

UNION ALL

SELECT year + 1
FROM prepare
WHERE year < 2030                     -- and last year is 2030
)
SELECT
    year, quarter
FROM prepare
CROSS JOIN ( VALUES (1), (2), (3), (4) ) AS tbl (quarter)

WITH prepare AS ( SELECT tbl.year FROM (VALUES (2017) ) AS tbl(year) -- for example, start year is 2k17 UNION ALL SELECT year + 1 FROM prepare WHERE year < 2030 -- and last year is 2030 ) SELECT year, quarter FROM prepare CROSS JOIN ( VALUES (1), (2), (3), (4) ) AS tbl (quarter)