2013-07-24 5 views
-1

У меня возникли проблемы с созданием повторяющейся переменной счетчика в SQL. Вот то, что я ищу, чтобы DO-Использование курсора для создания счетчика в SQL

x_id  date     num  p_id  Counter 
2113  4/1/2013    11   444   1 
2113  4/1/2013    11   445   2 
2113  4/1/2013    21   448   3 
2113  4/1/2013    21   460   4 
2113  4/1/2013    21   461   5 
2113  4/1/2013    31   463   6 
2116  4/1/2013    7    982   1 
2116  4/1/2013    7    985   2 
2116  4/1/2013    8    987   3 

Когда я заказываю эти данные по x_id, дате, NUM, и p_id, у меня есть все, как я хочу, чтобы это создать столбец счетчика.

У меня с трудом возникает разрыв и перезапуск этого столбца счетчика, где я хочу. Я хочу, чтобы счетчик запускался каждый раз при возникновении нового сопряжения x_id/date (поэтому, если оба изменения, счетчик должен вернуться к 1).

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

Похоже, что это должно быть относительно просто, что нужно сделать .. кто-нибудь может мне помочь?

Большое спасибо!

+0

Итак, в сценарии выше первые 6 строк должны иметь счетчик = 1, а последние 3 должны иметь счетчик = 2? –

+2

Какая система баз данных и какая версия указанной системы баз данных? –

+0

Спасибо за все ответы. Я использую MAMP и Sequel Pro на Mac, если это помогает. Какой идентификатор (как только данные упорядочены, как указано выше), для счетчика увеличивается на единицу для x_id/date pairings, а затем начинается с момента появления нового спаривания, поэтому счетчик должен выглядеть так, как он выше. –

ответ

1

решения для MySQL:

Вам не нужен курсор для этого

SELECT 
yt.*, 
@counter := CASE WHEN @prev_x != x_id OR @prev_date != `date` THEN 1 ELSE @counter + 1 END AS counter, 
@prev_x := x_id, 
@prev_date := `date` 
FROM yourTable yt 
, (SELECT @counter:=1, @prev_x:=NULL, @prev_date:=NULL) vars 
ORDER BY x_id, `date`, num, p_id 
+0

Хотя «дата» не изменяется в данных образца, повествование, похоже, говорит, что изменения «даты» также должны сбросить счетчик. –

+0

Это правильно. Я должен был сделать это более ясным, но дата изменится и сбросит счетчик. –

+0

Исправлено это, чтобы рассмотреть изменения столбцов даты. – fancyPants

3

Если вы используете систему базы данных, которая поддерживает функцию окна, то это ROW_NUMBER сек вакансии:

select x_id,date,num,p_id, 
    ROW_NUMBER() OVER (PARTITION BY x_id, date ORDER BY num, p_id) as counter 
from table 

SQL Server help for ROW_NUMBER(), но он также поддерживает многие другие системы баз данных, таких как Oracle, PostgreSQL, DB2 (но не MySQL):

Возвращает порядковый номер строки в пределах раздела результирующего набора, начиная с 1 для первой строки в каждом разделе

+1

+1 (за право). И 'row_number()' является стандартом ANSI и поддерживается большинством основных баз данных. По крайней мере: SQL Server, Oracle, DB2, Teradata и Postgres и многие его производные. –

+0

@GordonLinoff - добавил частичный список к моему ответу и выделил тот, который я думал о том, что я знаю, не поддерживает его (как всегда, было бы намного проще, если бы OP включила информацию о системе базы данных) –

+0

Это было бы прекрасно , но я использую MySQL. Любые другие предложения? –

0

Предполагая, что вы используете SQL Server/TSQL:

Не используйте курсор, вместо этого используйте функцию DENSE_RANK().

SELECT x_id, date, num, p_id, DENSE_RANK() OVER (ORDER BY x_id, date) as Counter FROM Table 

UPDATE: вопрос еще раз перечитайте, это не может быть правильным решением для приведенного выше сценария, он будет держать счетчик то же самое, пока соответствующие значения не изменятся (1 для 1-го шесть рядов, 2 для вторых трех и т. д.)

+0

' DENSE_RANK' является неправильной функцией, когда требуется счетчик. Он может присваивать одно и то же значение нескольким строкам. –

+0

Я верю, что это была оригинальная идея OP (задана в комментариях, но пока не получила ответа) –

+0

«происходит новое сопряжение x_id/date ... счетчик должен вернуться к 1» –

Смежные вопросы