当同一记录多次出现在表中时,如何返回永远不等于1的记录

时间:2018-11-30 14:31:24

标签: sql sql-server

ID  |  Is_Final   |    SEQ    |  State
-------------------------------------------
A1       0             12        Pending
A1       0             13        Quoted
B1       0             14        Pending 
B1       1             15        Quoted
C1       0             11        Pending 
C1       0             12        Pending
C1       0             13        Quoted


SELECT DISTINCT ID
FROM Table
WHERE ID NOT IN (SELECT ID FROM Table WHERE IS_FINAL = 1)

我已经在上面给出了查询,但是我想做的是返回所有不同的ID及其在表中ID的所有实例和最大Seq编号中IS_FINAL永远不等于1的状态。

基于相同的条件,我想返回:

ID    |   State
A1        Quoted
C1        Quoted

4 个答案:

答案 0 :(得分:4)

好的,我提出了一个非常简单的解决方案,该解决方案对您有效,并且应该很容易遵循。答案和演示是要遵循的最高解释。

create table #SOQ (
    ID char(2),
    Is_Final smallint,
    SEQ int,
    State varchar(30))

insert into #SOQ values ('A1', 0 , 12, 'Pending') 
insert into #SOQ values ('A1', 0 , 13, 'Quoted') 
insert into #SOQ values ('B1', 0 , 14, 'Pending') 
insert into #SOQ values ('B1', 1 , 15, 'Quoted') 
insert into #SOQ values ('C1', 0 , 11, 'Pending') 
insert into #SOQ values ('C1', 0 , 12, 'Pending') 
insert into #SOQ values ('C1', 0 , 13, 'Quoted') 

select distinct
    A.ID,
    State
from #SOQ as A
inner join (
    select 
        ID,
        Max(SEQ) as MaxSEQ
    from #SOQ
    where ID not in (
        select
            ID
        from #SOQ
        where Is_Final =1)
    group by ID) as B
    on A.ID = B.ID
    and A.SEQ = B.MaxSEQ

因此,在此查询的内部,我们将获取max序列号,因为您需要最新的值。

select 
    ID,
    Max(SEQ) as MaxSEQ
from #SOQ 

然后,我们需要消除所有带有final的值。我们可以通过某种形式的反连接来做到这一点。为简单起见,我选择了NOT IN,但是NOT EXISTS也可以工作,甚至可以做得更好。

select 
    ID,
    Max(SEQ) as MaxSEQ
from #SOQ
where ID not in (
    select
        ID
    from #SOQ
    where Is_Final =1)

然后在顶部,我们获取您不同的ID和State值,并加入该子查询以提供最终结果。

select distinct
    A.ID,
    State
from #SOQ as A
inner join (
    select 
        ID,
        Max(SEQ) as MaxSEQ
    from #SOQ
    where ID not in (
        select
            ID
        from #SOQ
        where Is_Final =1)
    group by ID) as B
    on A.ID = B.ID
    and A.SEQ = B.MaxSEQ

结果。

ID  State
A1  Quoted
C1  Quoted

我希望解释能帮助您到达需要去的地方。

编辑:我还添加了一个使用not exists来完成此操作的示例。

select distinct
    A.ID,
    State
from #SOQ as A
inner join (
    select 
        ID,
        Max(SEQ) as MaxSEQ
    from #SOQ as NE
    where not exists (
        select
            1
        from #SOQ 
        where Is_Final =1
            and NE.ID = ID )
    group by ID) as B
    on A.ID = B.ID
    and A.SEQ = B.MaxSEQ

答案 1 :(得分:1)

您可以将not existsrow_number()结合使用:

select top (1) with ties t.*
from table t
where not exists (select 1 from table t1 where t1.id = t.id and t1.IS_FINAL = 1)
order by row_number() over (partition by id order by seq desc);

答案 2 :(得分:1)

您可以尝试以下查询。

create table #temp (ID varchar(5), Is_Final int, SEQ int, States Varchar(20))

insert into #temp values ('A1', 0, 12, 'Pending'),
('A1', 0, 13, 'Quoted'),
('B1', 0, 14, 'Pending'), 
('B1', 1, 15, 'Quoted'), 
('C1', 0, 11, 'Pending'),
('C1', 0, 12, 'Pending'),
('C1', 0, 13, 'Quoted')

select * into #NewTable from
(
select ID, MAX(seq) as MaxSeq FROM #temp group by id
)a
-- delete from #NewTable where ID in (select distinct ID FROM #temp where Is_Final = 1)

select #temp.ID, States from #NewTable
inner join #temp on #NewTable.ID = #temp.ID and #temp.SEQ = 
#NewTable.MaxSeq
where #temp.ID not in (select distinct ID FROM #temp where Is_Final = 1)

drop table #NewTable
drop table #temp

输出如下

ID  States
A1  Quoted
C1  Quoted

在新表中,已选择并插入所有ID和最大序列。此后,所有is_final为1的ID都将被删除。 最后,根据Id和Max序列使用结果联接。

希望这会对您有所帮助。

答案 3 :(得分:0)

下面的查询将起作用:

SELECT ID,FstValue FROM
(
SELECT 
    ID,
    DENSE_RANK() OVER (PARTITION BY ID ORDER BY ID,SEQ DESC) RankOrder
    ,FIRST_VALUE(State) OVER (PARTITION BY ID ORDER BY ID) FstValue
FROM
    Table
WHERE 
    ID NOT IN (select DISTINCT ID from Table where Is_Final = 1)
    )m
WHERE RankOrder = 1

我已经使用DENSE_RANK()FIRST_VALUE函数来做到这一点。

最初,由于您没有列出的唯一PK值,因此请为每个IDSEQ组合生成该值。然后以降序获得每个组合的FIRST_VALUE(这很重要),这将有助于我们首先获取最新的行,然后将其过滤为第一行。