删除重复并保留MAX(id)mysql

时间:2018-10-02 09:33:49

标签: sql mariadb

我有一个代码,其中列出了数据库中数据的所有重复项

SELECT MAX(id) id 
FROM el_student_class_relation 
GROUP BY student_id, class_id 
HAVING COUNT(*) > 1

现在,我正在尝试保留MAX(id),然后应删除其余重复项

我尝试了代码

DELETE us 
FROM el_student_class_relation us
INNER JOIN(SELECT MAX(id) id 
            FROM el_student_class_relation 
            GROUP BY student_id, class_id HAVING COUNT(*) > 1) t ON t.id = us.id

但是它删除了MAX(ID)并保留了其他重复项,这与我想要的相反。

4 个答案:

答案 0 :(得分:4)

尝试

DELETE FROM el_student_class_relation 
WHERE id not in 
( 
        SELECT * from 
            (SELECT MAX(id) id 
            FROM el_student_class_relation 
            GROUP BY student_id, class_id) temp_tbl
) 

请注意: 请勿在内部查询中使用 HAVING COUNT(*)> 1 。 当只有一个具有相同ID的记录时,它将创建问题。

答案 1 :(得分:2)

您可以尝试执行以下查询,以删除存在另一个ID较高(并且班级和学生相同)的所有元素:

import sys
import matplotlib
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.patches import Rectangle


class MainWindow(QtW.QMainWindow):

  def __init__(self):
    super().__init__()
    self.setWindowTitle('MyWindow')
    self._main = QtW.QWidget()
    self.setCentralWidget(self._main) 

    # Set canvas properties
    self.fig = matplotlib.figure.Figure(figsize=(5,5))
    self.canvas = FigureCanvasQTAgg(self.fig)
    self.ax = self.fig.add_subplot(1,1,1)
    self.rect = Rectangle((0,0), 0.2, 0.2, color='k', fill=None, alpha=1)
    self.ax.add_patch(self.rect); self.rect.set_visible(False)
    self.canvas.draw()

    # set Qlayout properties and show window
    self.gridLayout = QtW.QGridLayout(self._main)
    self.gridLayout.addWidget(self.canvas)
    self.setLayout(self.gridLayout)
    self.show()

    # connect mouse events to canvas
    self.fig.canvas.mpl_connect('button_press_event', self.on_click)
    self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)


  def on_click(self, event):
    if event.button == 1 or event.button == 3:
    # left or right click: get the x and y coordinates
        if event.inaxes is not None:
          self.xclick = event.xdata
          self.yclick = event.ydata
          self.on_press = True

  def on_motion(self, event):
    # draw the square
    if event.button == 1 or event.button == 3 and self.on_press == True:
      if (self.xclick is not None and self.yclick is not None):
        x0, y0 = self.xclick, self.yclick
        x1, y1 = event.xdata, event.ydata
        if (x1 is not None or y1 is not None):
          self.rect.set_width(x1 - x0)
          self.rect.set_height(y1 - y0)
          self.rect.set_xy((x0, y0))
          self.rect.set_visible(True)
          self.canvas.draw() # self.canvas.drawRectangle(self.rect)


if __name__ == '__main__':
    app = QtCore.QCoreApplication.instance()
    if app is None: app = QtW.QApplication(sys.argv)
    win = MainWindow()
    app.aboutToQuit.connect(app.deleteLater)
    app.exec_()

答案 2 :(得分:1)

查询的直接解决方法是使用“反联接”,其中“非联接”是重要的功能。可以通过LEFT JOIN完成。

DELETE
  us 
FROM
  el_student_class_relation us
LEFT JOIN
(
  SELECT student_id, class_id, MAX(id) id 
    FROM el_student_class_relation 
GROUP BY student_id, class_id
-- HAVING COUNT(*) > 1  [Don't do this, you need to return ALL the rows you want to keep]
)
  gr
    ON gr.id = us.id
WHERE
  gr.id IS NULL  -- WHERE there wasn't a match in the "good rows" table

EDIT MariaDB和MySQL并非同一个人。 MariaDB确实允许在要删除的表上进行自我联接。

答案 3 :(得分:0)

在mysql(较低版本)中,如果删除子查询的工作方式有些不同,则必须使用比要求更多的层

DELETE FROM el_student_class_relation us
WHERE us.id not in 
( 
   select * from (
            SELECT MAX(id) id 
            FROM el_student_class_relation 
            GROUP BY student_id, class_id 
            ) t1
)