复杂查询,其中记录的最大值设置

时间:2014-09-03 01:39:26

标签: sql sql-server tsql

我有一些看起来像这样的数据

CandidateCategory
candidateCategoryId
candidateId
categoryId

我想返回特定categoryId是最新条目的所有记录,这个max(candidateCategoryId)

因此,如果一个候选人有5个类别,我想获得第23类的记录,但前提是这是最近添加的类别,即candidateCategoryId高于该类别的所有其他类别。

使用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。

7 个答案:

答案 0 :(得分:1)

首先尝试获取每个CandidateID的最大CandidateCategoryID,然后重新加入

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

因此,从您的示例数据中,内部预查询" MaxPerID"会生成两行......

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

然后,重新加入这两个包含你的AND CategoryID = 23的原始表只会返回第二个CandidateID条目

为了帮助澄清发布答案的其他人,该人似乎不想要最高的类别ID,但是如果你看一下它们,它们会被顺序添加 - 就像CandidateCategoryID的自动递增数字一样。因此,他们想要一个给定候选人的最新条目(因此候选人1和2)...如果最后一个条目是类别= 23,他们想要那个。

答案 1 :(得分: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
                 );

编辑:

如果您只想要max为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

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

我想出了这个

select    candidateCategoryId
from      candidateCategory
where     candidateCategoryId in (
    select    max(candidateCategoryId)
    from      candidateCategory
    group by  candidateId )
and       categoryId = 23

答案 5 :(得分:-1)

select * 
from  yourtable 
where  candidateCategoryId = (select max(candidateCategoryId) from yourtable)

答案 6 :(得分:-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
)