简体   繁体   中英

How to delete the rows with three same data columns and one different data column

I have a table "MARK_TABLE" as below.

How can I delete the rows with same "STUDENT" , "COURSE" and "SCORE" values?

| ID | STUDENT | COURSE | SCORE |
|----|---------|--------|-------|
| 1  |    1    |    1   |  60   |
| 3  |    1    |    2   |  81   |
| 4  |    1    |    3   |  81   |
| 9  |    2    |    1   |  80   |
| 10 |    1    |    1   |  60   |
| 11 |    2    |    1   |  80   |

Now I already filtered the data I want to KEEP, but without the "ID" ...

SELECT student, course, score FROM mark_table
INTERSECT
SELECT student, course, score FROM mark_table

The output:

| STUDENT | COURSE | SCORE |
|---------|--------|-------|
|    1    |    1   |  60   |
|    1    |    2   |  81   |
|    1    |    3   |  81   |
|    2    |    1   |  80   |

Use the following query to delete the desired rows:

DELETE FROM MARK_TABLE M
WHERE
    EXISTS (
        SELECT
            1
        FROM
            MARK_TABLE M_IN
        WHERE
            M.STUDENT = M_IN.STUDENT
            AND M.COURSE = M_IN.COURSE
            AND M.SCORE = M_IN.SCORE
            AND M.ID < M_IN.ID
    )

OUTPUT

在此输入图像描述

db<>fiddle demo

Cheers!!

使用distinct

SELECT distinct student, course, score FROM mark_table
select * from
(
select row_number() over (partition by student,course,score order by score) 
rn,student,course,score from mark_table
) t
where rn=1

Assuming you don't just want to select the unique data you want to keep (you mention you've already done this), you can proceed as follows:

  1. Create a temporary table to hold the data you want to keep
  2. Insert the data you want to keep into the temporary table
  3. Empty the source table
  4. Re-Insert the data you want to keep into the source table.

Use CTE with RowNumber

create table #MARK_TABLE (ID int, STUDENT  int, COURSE  int, SCORE  int)
insert into #MARK_TABLE 
values 
(1,1,1,60),
(3,1,2,81),
(4,1,3,81),
(9,2,1,80),
(10,1,1,60),
(11,2,1,80)

;with cteDeleteID as(
Select id, row_number() over (partition by student,course,score order by score) [row_number]  from #MARK_TABLE
)
delete from #MARK_TABLE where id in
(
 select id from cteDeleteID where [row_number] != 1
)

select * from #MARK_TABLE
drop table #MARK_TABLE    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM