删除连续重复的查询结果

时间:2016-06-05 02:35:57

标签: mysql sql oracle

您好我想知道如何从基于单列的查询结果中删除连续重复项。在这种情况下,null意味着他们不想购买任何东西,所以他们点击后退按钮。我想要买家的商品更改历史记录,并提供最早的购买信息。

选择项目,买方,buy_date 来自buy_date的项目订单

item           buyer           buy_date
null           Sam             04/24/2016
Lipstick       Anna            05/31/2016
Charger        Tim             06/01/2016
Charger        James           06/03/2016
null           Tim             06/03/2016
null           James           06/04/2016
Nail Polish    Sarah           06/04/2016

以下是测试结果示例。

现在我的新结果应该是

item           buyer           buy_date
null           Sam             04/24/2016
Lipstick       Anna            05/31/2016
Charger        Tim             06/01/2016
null           Tim             06/03/2016
Nail Polish    Sarah           06/04/2016

仅保留连续重复的第一个。我没有删除任何记录。我只是过滤掉结果,以便删除连续的重复项。

  1. 我如何在通用ANSI-SQL中执行此操作?
  2. 如果不可能,有没有办法在三大SQL供应商中做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以使用ANSI标准窗口功能执行此操作。一种方法使用lag()来获取上一个项目。然后,它总结项目更改的次数,并使用此信息查找每个组中的第一行:

select r.*
from (select r.*, row_number() over (partition by grp order by date) as seqnum
      from (select r.*,
                   sum(case when prev_item = item then 0 else 1 end) over (order by buy_date) as grp
            from (select r.*, lag(item) over (order by buy_date) as prev_item
                  from results r
                 ) r
           ) r
     ) r
where seqnum = 1;

嗯。我推翻了那一个。您只需要lag()

select r.*
from (select r.*, lag(item) over (order by buy_date) as prev_item
      from results r
     ) r
where prev_item is null or prev_item <> item;

答案 1 :(得分:0)

虽然我可能没有理解这个问题,但我会说最简单的方法是只根据它的名字来拉一个唯一的项目,只需在该字段上使用DISTINCT。所以新查询看起来像这样:

select DISTINCT(item), buyer, buy_date from item order by buy_date
编辑:没关系。我看到这个问题专门用于连续结果。见戈登的回应。

请注意,MySQL没有lag()函数,但我确实找到了这个帖子来模拟一个:Simulate lag function in MySQL

祝你好运!

答案 2 :(得分:0)

这是一个通用查询,如果他们不支持lagpartition by函数(如在MySQL中),可以在任何数据库上使用

select ITEM,BUYER,BUY_DATE from 
(
    select t1.item,
    max(t1.buyer) as buyer,
    max(t1.buy_date) as buy_date,
    count(*) as cnt
    from myTable t1
      inner join myTable t2
    on t1.item=t2.item
      and t1.buy_date <=t2.buy_date
    group by t1.item,t1.buy_date
)
where cnt=1

内部查询将根据buy_date派生计数,因此它会为每个item提供最新记录。如果您希望以其他方式获得结果,可以将连接条件更改为t1.buy_date >=t2.buy_date

内部查询将为您提供如下输出。

+-------------+-------+----------------------+-----+
|    ITEM     | BUYER |       BUY_DATE       | CNT |
+-------------+-------+----------------------+-----+
| Lipstick    | Anna  | 31-MAY-2016 00:00:00 |   1 |
| Charger     | James | 03-JUN-2016 00:00:00 |   1 |
| Charger     | Tim   | 01-JUN-2016 00:00:00 |   2 |
| Nail Polish | Sarah | 04-JUN-2016 00:00:00 |   1 |
+-------------+-------+----------------------+-----+

现在在外部查询中,给条件cnt=1仅获取不同的记录。