SQL-запрос для подсчета самой длинной строки последовательных оценок каждого из 7

684
Zero Cool

У меня есть таблица SQL, которая выглядит следующим образом (с именем в столбце A и счетом в столбце B):

 N. Name Score 1. Jim 7  2. Jim 4  3. Jim 4  4. Jim 7 5. Jim 7 6. Jim 7 7. Jim 7 8. Jim 4 9. Ted 4 10. Ted 4 11. Ted 7 12. Ted 7 . . . n. cont'd 

Мне нужно оценить каждого человека по наибольшему количеству последовательных результатов из 7.

Максимум 7 результатов Джима: 4, потому что он получил счет 7 четыре раза подряд. Тед макс 7 результат 2; это его максимальное количество. Если бы я искал макс 4, их оценки были бы равны двум.

Как мне получить функцию SQL-запроса в SSMS, чтобы сказать мне, какая самая длинная строка из 7 баллов (или любое заданное значение) была для каждого человека?

Это образец длинного списка, более 100 миллионов строк с 1 миллионом уникальных имен (на самом деле это уникальные числа, не имена, а в целях иллюстрации ...).

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

Боб 133 Джейн 117 Фил 106 ... Джим 4 Тед 2

Поэтому я думаю, что это начнется с SELECT DISTINCT, поэтому у моего результата есть все уникальные имена.

0
Когда у вас появится момент, посмотрите [Разница между ROW_NUMBER (), RANK () и DENSE_RANK ()] (https://blog.jooq.org/2014/08/12/the-difference-between-row_number- неприметный-DENSE_RANK /) Pimp Juice IT 7 лет назад 0
Спасибо, когда я сказал, что мне нужно ранжировать их по максимуму / минимуму, то, что я должен был сказать, я хотел бы знать, каково максимальное количество последовательных баллов для каждого человека, и я намереваюсь затем оценить эти значения высоко к низкому Это просто создает список без получения значения. Zero Cool 7 лет назад 0
Что именно ваш вопрос? Вы должны уточнить, «самая длинная строка из 7 баллов», последовательная строка или просто общее количество баллов выше 7? Ramhound 7 лет назад 0
Я ищу SQL-запрос для подсчета самой длинной строки последовательных баллов каждого человека по 7. Название переименовано соответственно. Благодарю. Zero Cool 7 лет назад 0

1 ответ на вопрос

0
Steve Mangiameli

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

  1. Фильтровать данные
  2. Внешне сгруппировать записи
  3. Создавайте реляционные группы и подсчитывайте результаты

Код

 --Test data create table #testRank ( RowNum int identity, Name nvarchar(255), Score int )  insert #testRank values ('Jim',7), ('Jim',4), ('Jim',4), ('Jim',7), ('Jim',7), ('Jim',7), ('Jim',7), ('Jim',4), ('Ted',4), ('Ted',4), ('Ted',7), ('Ted',7) -- I've added a second set of Jim data for testing, ('Jim',7), ('Jim',7), ('Jim',7), ('Jim',7)  --minimize the dataset; if your dealing with millions of rows, filter out the scores less than 7 select RowNum, Name  into #smallerDataSet from #testRank where score = 7;  --create groups or strings delineated by NULL values indicating the start and end of the string of scores about 7 select  x.RowNum, x.Name, Case when z.NextRow is null then null else x.RowNum-1 end PrevRow, Case when y.PrevRow is null then null else x.RowNum+1 end NextRow into #strings from #smallerDataSet x Left Join (select RowNum-1 PrevRow, Name from #smallerDataSet) y on y.PrevRow = x.RowNum and y.Name = x.Name Left Join (select RowNum+1 NextRow, Name from #smallerDataSet) z on z.NextRow = x.RowNum and z.Name = x.Name Where PrevRow is not null or NextRow is not null  --visulaize the query above select * from #strings  --use the ROW_NUMBER function to seperate the groups from each other; particularly important when the same name has the same string count --then simply do the math and order the list Select Distinct p.Name, EndStr-StartStr+1 MaxString from ( select ROW_NUMBER() over (order by RowNum) GroupNum, Name, RowNum StartStr  from #strings where PrevRow is null ) p join ( select ROW_NUMBER() over (order by RowNum) GroupNum, Name, RowNum EndStr from #strings where NextRow is null ) n on n.GroupNum = p.GroupNum and n.Name = p.Name order by MaxString desc  drop table #strings drop table #smallerDataSet drop table #testRank 
Во-первых, большое спасибо за то, что написали это. Это говорит недопустимое имя столбца для строк 53 и 54 для PrevRow, RowNum, Name и NextRow, и я не могу понять, почему. Я запускаю сценарий все вместе, и ранее работал по частям и добился успеха в создании #Strings. Может ли быть пропущенная запятая или что-то? Zero Cool 7 лет назад 0
Код работает на тестовых данных, которые я выложил. Вам нужно будет изменить его для работы со схемой таблиц. RowNum представляет значения в вашем примере для N. Steve Mangiameli 7 лет назад 0
Это замечательно. Я бегу сейчас. Я пробежал 100 строк, и он возвращает каждую строку больше двух, а не самую высокую для каждого «человека». Это своего рода неожиданная выгода, но это означает, что имя одного человека, вероятно, будет появляться много раз, а не один раз с наибольшей ценностью. Он также вернул временные таблицы. Я беспокоюсь, что это означает, что он будет держать все в оперативной памяти и сбой, прежде чем он завершит запись в файл. Я полагаю, что это будет очень долгая работа, поэтому, пожалуйста, поделитесь своими мыслями, если они у вас есть; иначе я опубликую, если и когда это будет успешно. Zero Cool 7 лет назад 0
Не бери в голову Стив. Это заняло всего 20 минут, чтобы записать в файл. Это проблемы с шампанским. Огромное спасибо! Zero Cool 7 лет назад 0
Временная таблица выбирается для вашей выгоды. Просто закомментируйте их, если они вам не нужны для устранения неполадок Steve Mangiameli 7 лет назад 0