2015-08-04 2 views
1

Используя T-SQL (SQL Server 2008 R2), я пытаюсь перечислить только строки со вторым самым высоким значением в конкретном столбце из таблицы temp, а затем поместить результаты в новую временную таблицу. ПК представляет собой ID, который может иметь увеличенные номера версий, а затем уникальные коды.Выделить все самые последние значения только из временной таблицы

Пример:

ID | Name| Version | Code 
------------------------ 
1 | A | 1  | 10 
1 | A | 2  | 20 
1 | A | 3  | NULL 
2 | B | 1  | 40 
2 | B | 2  | 50 
2 | C | 1  | 60 

Желаемый результат запроса является

ID | Version | Code 
------------------------ 
1 | 2  | 20 
2 | 1  | 40 

Для достижения этой цели мне нужно ниже запрос, чтобы быть адаптированы, чтобы вытащить второе наивысшее значение до тех пор, как результат дает номер версии больше 1. Эти результаты исходят из таблицы temp и затем будут помещены в таблицу результатов окончательных результатов. EDIT: обратите внимание, что это будет применяться к 33000 рядам данных, поэтому я предпочел бы что-то более аккуратное, чем INSERT VALUES. Благодарю.

Текущий запрос:

SELECT 
    ID 
    ,Version 
    ,Code 
INTO 
    #table2 
FROM 
    #table1 

SELECT * 
FROM #table2 
WHERE Version > 1 
ORDER BY ID asc 

DROP TABLE #table1 
DROP TABLE #table2 

Я попытался запустить, где положение WHERE Version < (SELECT MAX(VERSION) FROM #TABLE 2), но это не имеет никакого эффекта, предположительно из-за уникальные кодовые значения и в любом случае не будет работать там, где у меня есть более чем 3 Версии.

Идеи были бы с благодарностью получены.

Заранее спасибо.

ответ

0

я ИМЕЮ ИСПЫТАНИЕ код и он дает ВЫВОД согласно желаемому результату запроса является

SELECT ID,Name,[Version],Code 
FROM (
     SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY [Version] DESC) AS RNK,* 
     FROM 
      (
       SELECT 1 ID, 'A' Name ,1 [Version] ,10 Code 
       UNION ALL 
       SELECT 1, 'A', 2 ,20 
       UNION ALL 
       SELECT 1, 'A', 3 ,30 
       UNION ALL 
       SELECT 1, 'A', 4 ,NULL 
       UNION ALL 
       SELECT 2, 'B', 1 ,40 
       UNION ALL 
       SELECT 2, 'B', 2 ,50 
       UNION ALL 
       SELECT 2, 'C', 1 ,60 
      )B 
     )BASE 
WHERE RNK =2 
+0

Благодарим вас за решение, но, к сожалению, не практично из-за объема данных, с которыми я имею дело в действительности (33000 строк). Я обновил вопрос. – TJB

+0

Как за вами стол вы можете попробовать это: ВЫБРАТЬ ID, Имя, [Version] Код FROM ( \t ВЫБРАТЬ ID, Имя, [Version], код, ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY [ Версия] DESC) AS RNK \t FROM [Ваше имя таблицы] ) base WHERE RNK = 2 –

+0

Spot on - это было решение, которое я адаптировал к моему желаемому результату (вместо этого разбиение на версии). Большое спасибо. – TJB

0

Если ваш первичный ключ является только идентификатором, у вас есть повторяющиеся строки. Поэтому я предполагаю, что ваш первичный ключ - это нечто другое, например ID, Version, Name. У вас есть две строки с одинаковым идентификатором и той же версией, какое правило вы хотите применить к этому? Самый низкий номер?

я привел пример, который делает вид, что вы хотите:

Первый декларировать необходимые таблицы:

declare @table1 table (
    Id int, 
    Name nvarchar(20), 
    [Version] int, 
    Code int 
) 

insert into @table1 values (1,'A',1,10),(1,'A',2,20),(1,'A',3,30),(1,'A',4,NULL) 
          ,(2,'B',1,40),(2,'B',2,50),(2,'C',1,60); 

И тогда запроса, чтобы получить результаты:

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 group by Id 
) 
select 
    t1.Id, 
    t1.[Version], 
    min(t1.Code) as Code 
from 
    @table1 t1 
    inner join 
     HighestVersions hv 
     on 
      hv.Id = t1.Id 
      and (hv.MaxVersion-1) = t1.[Version] 
group by 
    t1.Id 
    ,t1.[Version] 

I должен был сделать небольшой грязный трюк с самым внешним выбором, это из-за дубликатов «Id» и «Version». Иначе вы бы получили две строки с ID = 2, Version = 1

Если вы хотите, чтобы удалить значение NULL можно изменить часть С (в зависимости от вашего последнего редактирования):

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 where Code is not null group by Id 
) 
+0

Спасибо за ваши предложения Joeri - вы правы в отношении ПК ... Идентификатор - это единственный ПК для другой таблицы, в который я, в конечном счете, присоединяюсь к этим результатам, так что это, вероятно, путаница. Тем не менее, это будет PK таблицы table2, которую я запросил выше. Ваше решение не будет работать для меня, потому что я на самом деле занимаюсь 33k + строками данных, поэтому мне нужно что-то немного аккуратно, чем вставлять все эти значения! – TJB

0

Попробуйте это :

DECLARE @List TABLE (ID int, Name char(1), Version int, Code int NULL) 

INSERT INTO @List 
VALUES 
(1, 'A', 1, 10), 
(1, 'A', 2, 20), 
(1, 'A', 3, 30), 
(1, 'A', 4, NULL), 
(2, 'B', 1, 40), 
(2, 'B', 2, 50), 
(2, 'C', 1, 60) 


SELECT 
    ID, Name, Version, Code 
FROM 
    (
    SELECT 
     *, 
     ROW_NUMBER() OVER (PARTITION BY ID, Name ORDER BY Version DESC) Rn 
    FROM @List 
    ) a 
WHERE 
    a.Rn = 2 
+0

Благодарим вас за решение, но, к сожалению, не практично из-за объема данных, с которыми я имею дело в действительности (33000 строк). Я обновил вопрос. – TJB

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