2012-06-21 6 views
2

가능한 중복 :
Delete duplicate rows 여기SQL 삭제 중복 행

내 테이블 구조입니다 :

"저자"(VARCHAR) | "점"(정수) | "Body"(텍스트)

저자는 항상 동일하며 몸도 마찬가지입니다. 동일한 작성자 항목이 다른 본문이있는 데이터베이스 전체에 여러 번 표시되므로 작성자에 따라 삭제할 수 없습니다. 그러나 포인트 열이 항상 동일하지는 않습니다. 가장 큰 포인트 값으로 행을 유지하고 싶습니다.

SQLite3과 Python을 사용하고 있습니다.

감사

편집 :

내가 이것을 시도했지만, 그냥 모든 행을 삭제합니다.

for row in cur.fetchall(): 
     rows = cur.execute('SELECT * FROM Posts WHERE Author=? AND Body=? AND Nested=? AND Found=?', (row['Author'], row['Body'], row['Nested'], row['Found'],)) 
     for row2 in rows: 
      delrow = row 
      if (row['Upvotes'] < row2['Upvotes'] or row['Downvotes'] < row2['Downvotes']): 
       delrow = row2 
      cur.execute("DELETE FROM Posts WHERE Author=? AND Body=? AND Upvotes=? AND Downvotes=? AND Nested=? AND Found=?", (delrow['Author'], delrow['Body'], delrow['Upvotes'], delrow['Downvotes'], delrow['Nested'], delrow['Found'],)) 
      dn += 1 
      print "Deleted row ", dn 

나는 이것을 시도했지만 작동하지 않았다.

cur.execute("DELETE FROM Posts WHERE Upvotes NOT IN (SELECT MAX(Upvotes) FROM Posts GROUP BY Body);") 

나는 또한 모든 변경 사항을 커밋하므로 변경되지 않습니다. SQLite3 모듈이 올바르게 설치되었고 DB에 쓸 수 있습니다.

+1

* 삐 소리 * 다시 스택 오버플로에 오신 것을 환영합니다. 모든 질문은 질문 형식으로되어 있는지 확인하십시오. 또한 정중하고 질문에 대한 답변을 수락하십시오. 좋은 하루 되세요. * 경고음 * –

+0

당신은 무엇을 시도 했습니까? 중복 행 삭제는 일반적으로 ROWNUMBER와 같은 일종의 순위 지정 기능을 사용하여 작성자와 본문을 분할합니다. – Bort

+0

다음을 시도해보십시오. http://stackoverflow.com/questions/6165895/delete-duplicate-rows, 특히 Vivek의 답변. (물론 가장 큰 포인트 값을 얻기 위해 부등식의 방향을 변경하고 싶습니다.) –

답변

2

불행히도 SQLite3에서는 partition over row과 같은 멋진 기능이 없으므로 하나의 쿼리에서 수행 할 수있는 방법이 없으므로 절차 적으로 또는 반복적으로 수행해야합니다.

성능상의 이유로 전체 삭제 가능성 목록을 추출한 다음 예를 들어 삭제하십시오.

# in your sql query 
SELECT ROWID, AUTHOR, BODY 
FROM TABLE_NAME 
ORDER BY AUTHOR, BODY, POINTS DESC 

그런 다음 파이썬 응용 프로그램에서, 당신의 결과 집합을 반복하고 저자/바디 콤보에 대한 모든 비 첫번째의 ROWID를 저장 (CTRL-BREAK 스타일의 프로그래밍 생각)하면 모든 작업이 완료되면 사용자의 설정을 구축 행 ID를 삭제하십시오.

나는 그것을 테스트하지 않았습니다
+1

이 유형의 삭제에는'partition over row'가 필요하지 않습니다. 변경되는 컬럼이 있기 때문에 ('points'). 행이 정확히 동일하지 않은 경우에만 필요합니다. 데이터를 추출하고 파이썬에서 처리 한 다음 결과를 db로 다시 푸시하는 것이 더 효율적이라는 것을 믿을 수 없을 것입니다. –

0

하지만,이 수도 일 : 그것은 당신이 원하는 keepwhat 할 경우 SELECT 쿼리와

DELETE FROM TableName 
    WHERE author, body, points NOT IN (SELECT author, body, MAX(points) as points 
     FROM TableName 
    GROUP BY author, body) 

실행 처음 볼. 당신이 가장 높은 포인트 값을 제외한 모든 삭제할 때문에

+0

포인트 열이 고유하지 않으면 작동하지 않습니다. 당신이 할 수있는 것은 inner select와 where 절에서'author, body, max (points)'를 리턴하는 것입니다. –

+0

감사합니다. 제안에 따라 예제를 업데이트했습니다. 나는 또한'body by'를'group by '문에 추가합니다. 필요하다고 생각합니다. – plntxt

+0

아, 네가'group by'에서 필요하다면 실패 할 것이다. 그렇지 않으면 실패 할 것이다. 그 중 하나를 놓쳤습니다. –

1

, 다음은 잘 그것을 할 것입니다 : 같은 저자가 모든 값을 삭제 한 후

delete from test 
    where exists (select * from test t2 
       where test.author = t2.author 
       and test.body = t2.body 
       and test.points < t2.points); 

은 기본 자체에 참여, 그리고 & 몸체는 낮지 만 포인트 값은 낮습니다. 여기

SqlFiddle : http://sqlfiddle.com/#!7/64d62/3

참고 : 하나 개주의 여러 저자/체 쌍은 동일한 최대 포인트 값을 가지고 있다면, 모든 값을 유지한다는 것이다.