获取具有特定重复值的行SQL

时间:2019-01-24 14:54:40

标签: mysql sql oracle

我有一个没有主键的表,看起来像:

NotId  Status
   1   active
   1   inactive
   2   active
   3   inactive
   4   inactive
   5   active
   5   inactive
   5   extended
   6   inactive
   6   extended

我想从表中获取所有的 NotId 。如果发现重复的 NotIds ,则仅返回状态为 有效的状态。与其他状态重复的 NotIds 应该被跳过。如果状态为有效 NotIds 不存在,则应返回所有重复项。请注意,状态不仅限于活动和非活动

预期结果:

1   active
2   active
3   inactive
4   inactive
5   active
6   inactive
6   extended

5 个答案:

答案 0 :(得分:1)

将分组与min一起使用

select NotId, min(Status) as Status
  from tab
 where Status in ('active','inactive') 
 group by NotId

Status in ('active','inactive')取决于评论

“应跳过具有其他状态的重复NotId”

答案 1 :(得分:0)

为每个NotId返回一行。将coalescecase表达式结合使用,以返回“ active”(如果存在),否则返回其他值。

select NotId,
       coalesce(min(case when Status = 'active' then Status end), min(Status)) as Status
from tab
group by NotId

答案 2 :(得分:0)

jarlh解决方案效果很好,但是如果要删除组大于1并且没有活动的行,则需要先做一些工作

SQL DEMO

SELECT `NotId`, CASE WHEN total = 1 
                     THEN result
                     WHEN active > 0 
                     THEN 'active'
                END as `Status`

FROM ( SELECT `NotId`, 
               MAX(`Status`) as result, 
               COUNT(*) as total,  
               COUNT( CASE WHEN `Status` = 'active' THEN 1 END) as active
       FROM Table1
       GROUP BY  `NotId`
  ) as T
WHERE total = 1 or active = 1;

答案 3 :(得分:0)

此查询满足规范。 (该规范可能与问题中给出的用例所需的规范不同。)

SELECT t.notid
     , t.status
  FROM mytable t 
  LEFT
  JOIN ( SELECT b.notid
              , b.status
           FROM mytable b
          WHERE b.status = 'active'
          GROUP
             BY b.notid
       ) n
   ON n.notid = t.notid
WHERE ( n.notid IS NULL OR t.status = 'active' )
ORDER
   BY t.notid
    , t.status

给出:

INSERT INTO mytable (notid, status) VALUES
 ('1','active')
,('1','inactive')
,('2','active')
,('3','inactive')
,('4','fee')
,('4','fi')
,('4','fo')
,('4','fum')
,('5','active')
,('5','active')
,('5','inactive')
;

查询返回:

notid  status
-----  ------
1      active
2      active
3      inactive
4      fee
4      fi
4      fo
4      fum
5      active
5      active

此查询假定notid为非NULL。当给定的notid存在“活动”状态的行时,这将返回表中的所有行,包括重复行,不包括状态为“活动”的行。

答案 4 :(得分:0)

我使用group_concat()分隔是否包含'active'的ID:

select tab.* 
from tab inner join (
  select NotId, concat(',', group_concat(Status), ',') like '%,active,%' active
  from tab
  group by NotId
) t
on t.NotId = tab.NotId
where
  t.active = 0
  or
  (t.active = 1 and tab.Status = 'active')

请参见demo
结果

| NotId | Status   |
| ----- | -------- |
| 1     | active   |
| 2     | active   |
| 3     | inactive |
| 4     | inactive |
| 5     | active   |
| 6     | inactive |
| 6     | extended |