Tsql 使用CTE自动递增的T-SQL

Tsql 使用CTE自动递增的T-SQL,tsql,auto-increment,Tsql,Auto Increment,我在使用常用表表达式进行简单的自动递增时遇到了问题。我不想要ROW_NUMBER,因为我将使用递增的条件,所以这里是我的问题的简化版本,仍然不起作用。我遇到以下错误:尝试以下操作时列名“n”无效: WITH NumberSongPair ( n,s ) AS ( SELECT 0 as n,SongKey as s from Songs where SongKey = 1 UNION ALL SELECT 1 + n as n,SongKey as s fro

我在使用常用表表达式进行简单的自动递增时遇到了问题。我不想要ROW_NUMBER,因为我将使用递增的条件,所以这里是我的问题的简化版本,仍然不起作用。我遇到以下错误:尝试以下操作时列名“n”无效:

 WITH NumberSongPair ( n,s ) AS (
    SELECT 0 as n,SongKey as s from Songs where SongKey = 1
    UNION ALL
    SELECT 1 + n as n,SongKey as s 
    from Songs 
    WHERE n < 500 )
SELECT n,s FROM NumberSongPair
OPTION ( MAXRECURSION 500 )
但添加了以下条件:“可删除”歌曲如果没有进入前3名,则排名将为空。这意味着SongKey 2不会下降,但4和6会下降。因此,输出将如下所示:

职位等级1-歌曲键2 职位等级2-宋基3 职位等级3-宋基4 职位等级4-歌曲键6 PositionRank null-宋键4 PositionRank null-宋键1
排名由分数决定,但也有条件

您应该使用rownumber,我不完全理解您想要什么,但这是一个如何使用rownumber的示例。您的正确脚本不起作用的原因是您没有将NumberSongPair和Songs加入联合部分。看来你没有什么可以加入他们的

declare @songs table (songkey int, base int, ctr int)

insert @songs values (1, 1, 1)
insert @songs values (2, 1, 1)
insert @songs values (3, 1, 1)

;WITH wrn AS (
select row_number() over(order by (select 1)) [rn], * from @Songs)
,a as
(
SELECT case 
when (base + 1)%2=0 then ctr
when ctr <=20 then ctr
else null end n,
case when (base + 1)%2=0 then ctr + 1
else ctr end CTR FROM WRN
)
SELECT n FROM a

如果您想让我编写一个脚本来完成您想要的任务,请向我提供一些示例数据、预期结果及其背后的逻辑。

对于第一个CTE,您的第二个SELECT子句使用Songs table,它可能没有n列;你应该用数字SONGPAIR把它连接起来。无论如何,了解你的表结构可能很有用。你能用简单的英语描述一下你的排名逻辑吗?你的问题可能更容易用RANK OVER函数解决,而不是递归,但这取决于你如何计算等级。编辑后在我的帖子中添加了更多内容。我想要递归,因为有时我想跳过一个基于条件的增量,然后再继续增量。我将尝试你所说的基于顺序将两者连接起来。也许每个表都有一个简单的行号,作为连接的开始。
WITH songs (songkey, dropable, points) AS (
  SELECT 1, 1,  1 UNION ALL
  SELECT 2, 1, 20 UNION ALL
  SELECT 3, 1,  3 UNION ALL
  SELECT 4, 0,  4 UNION ALL
  SELECT 5, 0, 11 UNION ALL
  SELECT 6, 0,  2
),
preliminaryRanking AS (
  SELECT
    rank1 = ROW_NUMBER() OVER (ORDER BY points DESC),
    *
  FROM songs
),
finalRanking AS (
  SELECT
    rank2 = ROW_NUMBER() OVER (
      ORDER BY
        CASE
          WHEN rank1 <= 3 OR dropable = 0 THEN rank1
          ELSE CAST(0x7FFFFFFF AS int)
        END
    ),
    *
  FROM preliminaryRanking
)
SELECT
  PositionRank = CASE WHEN rank1 <= 3 OR dropable = 0 THEN rank2 END,
  songkey, dropable, points
FROM finalRanking
ORDER BY rank1
declare @songs table (songkey int, base int, ctr int)

insert @songs values (1, 1, 1)
insert @songs values (2, 1, 1)
insert @songs values (3, 1, 1)

;WITH wrn AS (
select row_number() over(order by (select 1)) [rn], * from @Songs)
,a as
(
SELECT case 
when (base + 1)%2=0 then ctr
when ctr <=20 then ctr
else null end n,
case when (base + 1)%2=0 then ctr + 1
else ctr end CTR FROM WRN
)
SELECT n FROM a
WITH songs (songkey, dropable, points) AS (
  SELECT 1, 1,  1 UNION ALL
  SELECT 2, 1, 20 UNION ALL
  SELECT 3, 1,  3 UNION ALL
  SELECT 4, 0,  4 UNION ALL
  SELECT 5, 0, 11 UNION ALL
  SELECT 6, 0,  2
),
preliminaryRanking AS (
  SELECT
    rank1 = ROW_NUMBER() OVER (ORDER BY points DESC),
    *
  FROM songs
),
finalRanking AS (
  SELECT
    rank2 = ROW_NUMBER() OVER (
      ORDER BY
        CASE
          WHEN rank1 <= 3 OR dropable = 0 THEN rank1
          ELSE CAST(0x7FFFFFFF AS int)
        END
    ),
    *
  FROM preliminaryRanking
)
SELECT
  PositionRank = CASE WHEN rank1 <= 3 OR dropable = 0 THEN rank2 END,
  songkey, dropable, points
FROM finalRanking
ORDER BY rank1
PositionRank         songkey     dropable    points
-------------------- ----------- ----------- -----------
1                    2           1           20
2                    5           0           11
3                    4           0           4
NULL                 3           1           3
4                    6           0           2
NULL                 1           1           1