Фильтрация данных с использованием двух столбцов в T-SQL - PullRequest
2 голосов
/ 14 июля 2011

У меня есть файлы, которые имеют версии с использованием основной и вспомогательной версии.
Теперь я хочу получить самые высокие версии всех файлов (что я уже сделал). Затем проверьте второстепенные версии, чтобы увидеть, содержит ли он 0. Если он выбрасывает весь этот набор версий. Так, например. Мой первый запрос возвращает:

FileA Ver 1.0, 1.1, 1.2, 1.3 
FileB Ver 2.1, 2.2, 2.3, 2.4 
FileC Ver 5.1, 5.2, 5.3. 

Так во всех 11 строках / записях. Теперь мой второй запрос должен взять этот результат и выбросить все версии FileA, потому что одна из версий имеет младшую версию 0. Таким образом, второй запрос должен вернуть:

FileB Ver 2.1, 2.2, 2.3, 2.4 
FileC Ver 5.1, 5.2, 5.3. 

7 строк / записей всего. Может ли кто-нибудь помочь мне с этим запросом? Я использую SQL Server 2008, если это поможет.

latestFileMajorVersion(fileId, majRev)
as
(
    --Gets files with highest major version
    select distinct v_fileid, max(v_majrev)
    from files
    group by v_fileid
),
latestFileVersions(fileId, majRev, minRev)
as
(
    --Gets files with highest major version and all minor versions
    select fileId, majRev, minrev
    from files
    inner join latestFileMajorVersion on files.v_fileid = latestFileMajorVersion.fileId
    where v_majrev = latestFileMajorVersion.majRev
),
latestFileVersion(fileId, majRev, minRev)
as
(
    select fileId, majRev, minrev
    from latestFileVersions
    where --I'm stuck here.
)
select v_fileid, v_majrev, v_minrev, v_status
from files
inner join latestFileVersion on v_fileid = latestFileVersion.fileId
where latestFileVersion.majRev = v_majrev and latestFileVersion.minRev = v_minrev and v_status = 'UnAssigned'

Таблица:

CREATE TABLE [dbo].[Files](
    [v_fileid] [uniqueidentifier] NOT NULL,
    [v_libid] [uniqueidentifier] NOT NULL,
    [v_userid] [uniqueidentifier] NOT NULL,
    [v_majrev] [int] NOT NULL,
    [v_minrev] [int] NOT NULL,
    [v_status] [nvarchar](16) NOT NULL,
 CONSTRAINT [PK_Files] PRIMARY KEY CLUSTERED 
(
    [v_fileid] ASC,
    [v_majrev] ASC,
    [v_minrev] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [IX_Files] UNIQUE NONCLUSTERED 
(
    [v_majrev] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [IX_Files] UNIQUE NONCLUSTERED 
(
    [v_minrev] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Ответы [ 3 ]

1 голос
/ 14 июля 2011

Вы можете переписать ваш запрос, используя эту идею для синтаксиса.Он работает для предоставленных вами образцов данных.

declare @t table (fileid varchar(10), [version] varchar(5))

insert @t values('FileA','1.0')
insert @t values('FileA','1.1')
insert @t values('FileA','1.2')
insert @t values('FileA','1.3')
insert @t values('FileB','2.1')
insert @t values('FileB','2.2')
insert @t values('FileB','2.3')
insert @t values('FileB','2.4')
insert @t values('FileC','5.1')
insert @t values('FileC','5.2')
insert @t values('FileC','5.3')

SELECT * FROM @t t 
WHERE NOT EXISTS 
(SELECT 1 FROM @t WHERE PARSENAME([version], 1) = '0' AND t.fileid = fileid)
0 голосов
/ 14 июля 2011

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

Так что мне интересно, если 1) я переборол это решение и 2) есть ли более "элегантный" или умный способ написать это. Все комментарии, критика и / или предложения приветствуются.

;with solution(fileId, majrev, minrev, status, checkid, maxrev) 
as
(
select *
from files
inner join
(
    select v_fileid, MAX(v_majrev) as max_major
    from files
    group by v_fileid
) as max_versions on max_versions.v_fileid = files.v_fileid and 
                     max_major = files.v_majrev
except                   
select *
from files
inner join
(
    select v_fileid, MAX(v_majrev) as max_major
    from files
    where v_minrev = 0
    group by v_fileid
) as unwanted_versions on unwanted_versions.v_fileid = files.v_fileid and 
                          max_major = files.v_majrev
)
select *
from solution
0 голосов
/ 14 июля 2011

Вот рабочее решение с небольшим примером стола, с которым вы можете играть. Выполните его точно так же, как и без других SQL вокруг него. Затем вы можете изменить его в соответствии с вашими потребностями.

declare @files table (fileId int identity(1,1), majRev int, minRev int)
insert into @files values (1,0)
insert into @files values (1,1)
insert into @files values (2,0)
insert into @files values (2,2)
insert into @files values (3,1)
insert into @files values (3,2)
insert into @files values (4,1)

 select fileId, majRev, minRev
   from @files f
  where not exists 
        (select *
           from @files
          where minRev = 0
            and majRev = f.majRev
            and fileId = f.fileId)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...