删除表A中每个ID小于最高ID的所有行

时间:2018-10-31 21:46:23

标签: sql sql-server tsql

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new ViewPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class ViewPanel extends JPanel {

        private static int APP_WIDTH = 600;
        private static int APP_HEIGHT = 400;

        private static final long serialVersionUID = -8019663913250286271L;

        public ViewPanel() {
            setBackground(Color.GRAY);
            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.start();
        }

        public void init() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(APP_HEIGHT, APP_HEIGHT);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            render(g);
        }

        // Where I do the drawing. It's called from the rendering loop in the JFrame
        public void render(Graphics g) {

            // refresh the background since we're not relying on paintComponent all the time
            Color bgc = getBackground();
            g.setColor(bgc);
            g.fillRect(0, 0, APP_WIDTH, APP_HEIGHT);

            // just paint a moving box
            drawBox(g);

            // draw a line to prove correctness. In the loop, you can see part of this line is hidden
            // underneath the title bar
            g.setColor(Color.red);
            g.drawLine(0, 0, APP_WIDTH, APP_HEIGHT);
        }

        protected void drawBox(Graphics g) {

            // get a random color
            Random ran = new Random();
            int red = ran.nextInt(255);
            int grn = ran.nextInt(255);
            int ble = ran.nextInt(255);
            Color colour = new Color(red, grn, ble);
            g.setColor(colour);

            // get a random position        
            int x = ran.nextInt(APP_WIDTH - 50);
            int y = ran.nextInt(APP_HEIGHT - 50);

            // draw it
            g.fillRect(x, y, 50, 50);
        }
    }
}

结果:

create Table A
(
 ID Int,
 Name Varchar(10)
)

Insert Into A Values(1,'A'),
                    (1,'B'),
                    (2,'A'),
                    (3,'A'),
                    (3,'C'),
                    (2,'B'),
                    (2,'C'),
                    (1,'C'),
                    (4,'C'),
                    (4,'B')
SELECT * FROM A ORDER BY NAME,ID

如果我在下面的查询中运行此代码:

ID  Name
1   A
2   A
3   A
1   B
2   B
4   B
1   C
2   C
3   C
4   C

结果:

;WITH CTETEST
AS
(
SELECT MAX(ID)[MAXID],Name FROM A GROUP BY NAME
)


SELECT  max([MAXID])[ID],A.Name FROM CTETEST 
 join A
 on A.ID=CTETEST.MAXID
  GROUP BY A.NAME

我希望在主基表中设置以上结果,并删除其余的名称,该名称要小于每个Name类别下的最高ID。请建议我一些疑问。

2 个答案:

答案 0 :(得分:1)

我将在SQL Server中使用可更新的CTE:

with todelete as (
      select a.*, max(id) over (partition by name) as maxid
      from a
     )
delete todelete from todelete
     where id < maxid;

在几乎所有数据库中,您都可以使用:

delete a
    where id < (select max(id) from a a2 where a2.name = a.name);

答案 1 :(得分:0)

您可以尝试用deleteCTE,在order by ID desc中用名称CTE来创建行号。

然后仅保留rn = 1行数据。

;with cte as(
     SELECT *,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY ID desc) rn FROM A
)
delete cte
where rn > 1

(example)