2016-06-05 6 views
0

안녕하세요, 단일 열을 기반으로 쿼리 결과에서 연속 된 중복을 제거하는 방법을 알고 싶습니다. 이 경우 null은 아무 것도 구입하지 않으려 고 버튼을 다시 클릭한다는 의미입니다. 가장 빠른 구매 정보로 구매자의 아이템 변경 기록을 원합니다.연속 된 중복 쿼리 결과 제거

선택 항목, 구매자, 매입 일 다음

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 공급 업체에서이 방법을 사용할 수 있습니까?
+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; 
+0

덕분에, 그것은 내가 두 번째에 필요한 것이 었습니다. –

+0

안녕하세요. 실제로 문제가 있습니다. 널 (null)의 경우에는 작동하지 않습니다. 그래서 처음 세 항목이 null 인 경우 첫 번째 항목을 가져 가지 않습니다. (null은 구매 또는 무시되지 않음을 의미) –

+0

@ ChunpingWang. . . 실제로, 나는 그것이 3 개의 모든 'NULL'항목을 가져야한다고 생각합니다. 정확히 무슨 일이 일어나고있는거야? 다른 질문으로 설명하는 것이 더 쉬울 수도 있습니다. –

0

내가 가장 간단한 방법은 이름에 따라 단 하나의 고유 한 항목을 끌어 말할 것 질문을 이해하지 않을 수 있지만 그것은 단지 그 필드에 DISTINCT 사용. 따라서 새 쿼리는 다음과 같습니다.

select DISTINCT(item), buyer, buy_date from item order by buy_date 

EDIT : Nevermind. 나는이 질문이 특히 연속 된 결과를위한 것이라고 생각한다. 고든의 반응을보십시오. Simulate lag function in MySQL

행운을 빕니다 : MySQL은() 함수 지연이없는하지만 난 하나를 시뮬레이션이 게시물을 찾기 위해 관리 않았다

주의!

0

이 그들이 (MySQL은 같은) lag 또는 partition by 기능을 지원하지 않을 경우 데이터베이스에 사용 될 수있는 일반 쿼리

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을 사용하여 다른 레코드 만 가져옵니다.

+0

lexigraphically 최대 구매자 이름이 최대 구매 날짜와 일치하지 않으면'max (t1.buyer)'를 사용하는 데 문제가 없습니까? –

+0

이것은 규칙을 우회하기위한 것입니다.'select by 컬럼이 select에서 사용된다면, 그 컬럼에 대해 aggregate 함수를 사용하거나'by group by'을 사용해야합니다. 그것은 어쨌든 출력을 변경하지 않습니다. – Utsav