从一组至少具有此状态的重复记录中选择具有给定状态的一条记录

时间:2018-05-09 00:53:52

标签: sql sqlite

我有一个系统通过向外部系统发送3个参数来请求信息:user,start_date和end_date。

我有一张桌子

request (
  id, 
  user, 
  start_date, 
  end_date, 
  status
) 

记录这些请求及其状态(Done表示已返回的请求,Waiting表示尚未返回的请求。

我会每隔几个小时重新提交尚未返回的请求,即使初始请求仍可能在将来返回一段时间。

一段时间后,我的表会有多个同一个用户/ start_date / end_date的请求,其中一些是等待,一些是完成。

我需要的是一个查询,它返回所有重复请求的ID列表,但1 Done除外,其中至少有一个请求的status = Done。

总之,我需要一种方法来清除给定用户/ start_date / end_date的超出请求,如果其中至少有一个状态=完成(无论哪一个,我只需要保持1状态=完成给定的用户/ start_date / end_date)。

到目前为止,我已经能够确定至少有一次完成的重复请求。要从这个查询中选择除了一个完整的所有完成,我很可能将整个查询包装成另外两个选择并执行魔术,但查询原样,已经非常慢。有人可以帮我重构它并选择我需要的最终结果吗?

http://sqlfiddle.com/#!5/10c25a/1

我正在使用SQLite

sqlfiddle中提供的数据集的预期结果是:

454, 457, 603, (604 or 605 not both), 607, 608

2 个答案:

答案 0 :(得分:2)

select r.id from request r inner join (
    select user, start_date, end_date,
        min(case when status = 'Done' then id end) as keep_id
    from request
    group by user, start_date, end_date
    having count(case when status = 'Done' then 1 end) > 0 and count(*) > 1
) s on  s.user = r.user and s.start_date = r.start_date and s.end_date = r.end_date
    and s.keep_id <> r.id

答案 1 :(得分:1)

您所追求的是符合此标准的记录......

  • 存在Status“完成”的另一条记录
  • 其他“完成”记录与userstart_dateend_date
  • 相匹配
  • 其他记录的id值较低(因为您需要某些来识别记录保持其他记录的id更高,但您正在查看的记录有Status“正在等待”

考虑到所有这些,这是您的查询

SELECT id FROM request r1
WHERE EXISTS (
  SELECT 1 FROM request r2
  WHERE r2.Status = 'Done'
  AND r1.user = r2.user
  AND r1.start_date = r2.start_date
  AND r1.end_date = r2.end_date
  AND (r1.id > r2.id OR r1.Status = 'Waiting')
)
ORDER BY id

http://sqlfiddle.com/#!5/10c25a/26〜生成ID 454,457,603,605,607和608