T-SQL с использованием CTE для автоинкремента - PullRequest
2 голосов
/ 19 июля 2011

У меня проблемы с простым автоинкрементом с использованием общих табличных выражений.(Я не хочу 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 )

Почему он не может распознать 'n' как вновь созданный увеличенный столбец?Я даже был бы рад просто избавиться от первого выбора все вместе, пока я могу продолжать увеличивать число при выборе столбцов из таблицы.

Если вам интересны мои общие цели, то это ранжирование песен.... с такими условиями:

 WITH Nbrs ( base, n,ctr ) AS (
    SELECT 0,0,0 UNION ALL
    SELECT 1 + base,'n' = case 
                        when (base + 1)%2=0 then ctr
                        when ctr <=20 then ctr
                        else null end,
                 'ctr' = case
                        when (base + 1)%2=0 then ctr + 1
                        else ctr end
    FROM Nbrs WHERE base < 500 )
SELECT n FROM Nbrs
OPTION ( MAXRECURSION 500 )

РЕДАКТИРОВАТЬ ...

Извините, мое объяснение было не очень хорошим.Я просто хотел добавить еще один столбец с автоинкрементом psuedo, который иногда мог бы обнуляться вместо приращения.В основном я пытаюсь что-то вроде этого:

declare @songs table (songkey int, dropable bit, points int)

insert @songs values (1, 1, 1); insert @songs values (2, 1, 20);
insert @songs values (3, 1, 3); insert @songs values (3, 0, 11); 
insert @songs values (4, 0, 4); insert @songs values (6, 0, 2); 

select row_number() over(order by points desc) as RankingPosition, songkey, dropable, points 
from @Songs

Но добавив следующее условие: «отбрасываемые» песни теряют свой рейтинг (являются нулевыми), если они не попадают в топ-3. Это означает, что SongKey # 2не упадет, но № 4 и № 6 будут.Таким образом, результат будет выглядеть следующим образом:

  • PositionRank 1 - Songkey 2
  • PositionRank 2 - Songkey 3
  • PositionRank 3 - Songkey 4
  • PositionRank4 - Songkey 6
  • PositionRank null - Songkey 4
  • PositionRank null - Songkey 1

Ранг определяется точками, но есть условия.

Ответы [ 2 ]

1 голос
/ 19 июля 2011
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
0 голосов
/ 19 июля 2011

Вы должны использовать rownumber, я не понимаю на 100%, что вы хотите, но это пример того, как вы можете использовать rownumber.Причина, по которой ваш corrent-скрипт не работает, заключается в том, что вы не присоединились к 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

Если вы хотите, чтобы я написал сценарий, чтобы делать то, что вы хотите, предоставьте мне несколько примеров данных, ожидаемый результат и логику этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...