2014-09-03 4 views
-1

У меня есть данные, что выглядит как этоткомплексов запросов, где запись макс в наборе

CandidateCategory 
candidateCategoryId 
candidateId 
categoryId 

Я хочу, чтобы вернуть все записи, в которых конкретный CategoryId является наиболее последней записью, этот максимум (candidateCategoryId)

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

Использование MS SQL 2012

Выборочные данные в формате

candidateCategoryId candidateId categoryId 
    100    1    10 
    101    1    11 
    102    1    50 
    103    1    23 
    104    1    40 

нет результата, 23 не максимальная candidateCategoryId

candidateCategoryId candidateId categoryId 
    200    2    20 
    201    2    31 
    202    2    12 
    203    2    23 

возвращаемый результат, 23 это максимум candidateCategoryId для этого кандидат.

+0

Это может быть полезно прочитать вопрос, который имеет схему, имя таблицы и 3 поля. –

ответ

0

Я придумал этот

select candidateCategoryId 
from  candidateCategory 
where  candidateCategoryId in (
    select max(candidateCategoryId) 
    from  candidateCategory 
    group by candidateId) 
and  categoryId = 23 
-1
select * 
from yourtable 
where candidateCategoryId = (select max(candidateCategoryId) from yourtable) 
+0

Обычно это возвращает ровно одну строку. –

+0

true. Попытка прочитать ум OP. Угадай, что я использовал неправильный хрустальный шар. – Squirrel

0

Это основная проблема «наибольшего из n». Вы можете решить эту проблему с not exists, среди прочего:

select t.* 
from somedata t 
where not exists (select 1 
        from somedata t2 
        where t2.categoryId = t.categoryId and 
         t2.candidateCategoryId > t.candidateCategoryId 
       ); 

EDIT:

Если вы хотите только категории, где Макс 23, а затем добавить еще одно условие:

select t.* 
from somedata t 
where not exists (select 1 
        from somedata t2 
        where t2.categoryId = t.categoryId and 
         t2.candidateCategoryId > t.candidateCategoryId 
       ) and 
     t.categoryId = 23 
+0

Как это проверить на конкретную категорию? Например, как 23? –

+0

@DaleFraser. , , Собственно, вы отредактировали вопрос, и теперь я не уверен, чего вы хотите. Это возвращает данные для строки с максимальным идентификатором категории. –

+0

Я представил только примеры по запросу, всегда заданный вопрос для определенной категории. 23. Мне нужны только записи, где this categoryId является максимальным id для кандидата. –

0
select * 
    from (select t.* 
      from tbl t 
      join (select candidateid, 
         categoryid, 
         max(candidatecategoryid) as lastid 
       from tbl 
       group by candidateid, categoryid) v 
      on t.candidateid = v.candidateid 
      and t.categoryid = v.lastid) x 
where categoryid = 23 
-1
declare @categoryId int 

select @categoryId = 23 

with cte as 
(
    select candidateCategoryId, candidateId, categoryId, 
     rn = row_number() over (partition by candidateId order by candidateCategoryId desc) 
    from yourtable 
) 
select * 
from cte c 
where exists 
(
    select * 
    from cte x 
    where x.candidateId = c.candidateId 
    and x.rn  = 1 
    and x.categoryId = @categoryId 
) 
0

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

DECLARE @candidates TABLE (CandidateCategoryId int,CandidateId int,CategoryId int) 

INSERT INTO @candidates 
SELECT 100, 1, 10 
UNION 
SELECT 101, 1, 11 
UNION 
SELECT 102, 1, 50 
UNION 
SELECT 103, 1, 23 
UNION 
SELECT 104, 1, 40 
UNION 
SELECT 200, 2, 20 
UNION 
SELECT 201, 2, 31 
UNION 
SELECT 202, 2, 12 
UNION 
SELECT 203, 2, 23 

SELECT * FROM @candidates c 
JOIN 
(
SELECT CandidateId,MAX(CategoryId) AS CategoryId FROM @candidates 
GROUP BY CandidateId 
) tmp 
ON c.CandidateId = tmp.CandidateId 
AND c.CategoryId = tmp.CategoryId 

И получить результаты, которые выглядят как

CandidateCategoryId | CandidateId | CategoryId 
---------------------------------------------- 
201     | 2  | 31 
102     | 1  | 50 
1

Попробуйте получить максимальную CandidateCategoryID за CandidateID Во-первых, а затем вновь присоединиться назад

select 
     yd2.* 
    from 
     (select yd.candidateID, 
       max(yd.candidateCategoryId) as maxCandCatID 
      from YourData yd 
      group by yd.candidateID) MaxPerID 
     JOIN YourData yd2 
      on MaxPerID.candidateID = yd2.candidateID 
      AND MaxPerID.maxCandCatID = yd2.CandidateCategoryID 
      AND yd2.categoryID = 23 

Таким образом, из данных образцов, внутренний prequery "MaxPerID" будет генерировать два ряда ...

CandidateID MaxCandCatID (and ultimately corresponds to category ID) 
1    104   40 
2    203   23 

Затем повторно присоединиться к исходной таблице на эти два включая ваши и CategoryID = 23 будет возвращать только второй вход CandidateID

И, чтобы помочь разъяснить другим, которые опубликовали ответы, человек не по-видимому, требуется идентификатор наивысшей категории, но если вы посмотрите на них, они последовательно добавляются - как автоинкрементный номер для кандидата CandidateCategoryID. Итак, они хотят самую последнюю запись для данного кандидата (отсюда кандидаты 1 & 2) ... и если последняя сделанная запись была в категории = 23, они хотят ТОТ один.

+0

Направил меня в правильном направлении –