根据结果​​集中的Last Values过滤SQL查询

时间:2015-09-04 10:29:36

标签: sql sql-server

我的表格Sample包含IdPosition列。

select ID ,POSITION
from SAMPLE
order by 1

示例:

ID  Position
1   GEN2
1   GEN1
2   GEN1

2   GEN4
2   GEN2
2   GEN3
3   GEN1
4   GEN1
5   GEN1
5   GEN1
5   GEN1
5   GEN4
6   GEN1  

在这里,我需要根据以下条件选择记录......

如果每个唯一id的最后一条记录的值为GEN1,那么我需要过滤并选择它。

所以我希望结果集如下:

ID  Position
1   GEN1
3   GEN1
4   GEN1
6   GEN1  

由于id' s(2,5)在最近的记录中没有值GEN1,我忽略了它...

4 个答案:

答案 0 :(得分:4)

如果您有history_id,则可以使用row_number()

select h.*
from (select h.*,
             row_number() over (partition by id order by history_id desc) as seqnum
      from history h
     ) h
where seqnum = 1 and Position = 'GEN1';

答案 1 :(得分:2)

使用row_number()分区的id,并在公共表表达式中按降序排列history_id

WITH CTE AS (
   SELECT 
      rn = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY History_id DESC) 
      , *
   FROM Sample 
) 
SELECT * FROM CTE
WHERE Position = 'GEN1' AND rn = 1;

另一种解决方案是使用带有相关子查询的否定exists谓词:

SELECT ID, Position
FROM Sample s
WHERE Position = 'GEN1'
AND NOT EXISTS (
    SELECT 1 
    FROM Sample 
    WHERE Position <> 'GEN1' 
      AND History_id > s.History_id AND ID = s.ID
    );

使用row_number的版本在适当的索引支持时最有可能表现得更好(例如:(id, history_id desc, position))。

答案 2 :(得分:0)

这是一个很长的方法所以请理解。此外,如果你是一个更好的解决方案,我会很高兴看到它,因为它也会帮助我!

首先,我创建了一个临时表,每个ID的行数最多。

SELECT 
   OutTable.row
   , OutTable.[ID]
   , OutTable.Position
INTO #tmp_result
FROM (
   SELECT 
      ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID ASC) as row
      , [ID]
      , Position
   FROM #test 
) AS OutTable

和输出都是这样的..

enter image description here

然后,查找每个ID的最大行,并过滤所有当前行=最大行和位置=&#39; GEN1&#39;

结果BEFORE WHERE [max_row] = [row]和Position =&#39; GEN1&#39;

enter image description here

SELECT 
    ID
    , Position 
FROM (
    SELECT
        t.row
       , t.[ID]
       , t.Position
        , (SELECT MAX(row) FROM #tmp_result WHERE ID = t.ID) AS [max_row]
    FROM #tmp_result t
) AS T
WHERE
    [max_row] = [row]
AND Position = 'GEN1'

这是WHERE之后的结果。 (使用指定的列)

enter image description here

答案 3 :(得分:-1)

Select * from sample where id IN(Select distinct ID from sample where Position="GEN1" order by id DESC)