SQL Server - 基于两个表的SUM的条件DELETE

时间:2017-09-20 15:15:59

标签: sql-server

如果指定的学生的分数达到x sPoints以上的值,我想从Studies表中删除指定的学生。我确实试图这样做,如果我只指定它们必须在下面的分数,它就有效。

如果我开始在查询中指定学生ID和学期编号,它会删除所有来自Study的学生,其中学生ID和术语与查询中的学生ID和术语匹配,而无需检查分数。

我的尝试:学生S2在第2学期总共有45分(HasStudied中有5分,Studies中有40分)所以他不应该使用此查询删除。但是当我运行此查询时,他仍然会被删除。

我在MS SQL server 2014上。

DELETE FROM Studies
FROM Studies a1
INNER JOIN (SELECT a.stID AS ha 
            FROM Studies a 
            INNER JOIN HasStudied wq ON wq.stID = a.stID 
            WHERE a.stID = 'S2' AND a.termNbr = 2 
            GROUP BY a.stID 
            HAVING (SUM(wq.sPoints) + (SUM(a.sPoints))) > 50) a2 ON a1.stID = a2.ha

Studies

CREATE TABLE Studies 
(
    cID VARCHAR (5) NOT NULL,
    stID VARCHAR (5) NOT NULL,
    sPoints int,
    termNbr int

    CONSTRAINT STUDIES_PK PRIMARY KEY (cID, stID),

    CONSTRAINT STUDIES_CID_FK 
        FOREIGN KEY (cID) REFERENCES Course (cID),
    CONSTRAINT STUDIES_STID_FK 
        FOREIGN KEY (stID) REFERENCES Student (stID)
)

HasStudied

CREATE TABLE HasStudied 
(
    cID VARCHAR (5) NOT NULL,
    stID VARCHAR (5) NOT NULL,
    grade VARCHAR (5),
    sPoints int,
    termNbr int

    CONSTRAINT HASSTUDIED_PK PRIMARY KEY (cID, stID)
    CONSTRAINT HASSTUDIED_CID_FK 
        FOREIGN KEY (cID) REFERENCES Course (cID),
    CONSTRAINT HASSTUDIED_STID_FK 
        FOREIGN KEY (stID) REFERENCES Student (stID)
)

HasStudies和研究中的数据。

INSERT INTO HasStudied (cID, stID, grade, sPoints, termNbr) VALUES 
('K1', 'S2', 'D', (SELECT cPoints FROM COURSE WHERE cID = 'K1'), 1), 
('K2', 'S2', 'A', (SELECT cPoints FROM COURSE WHERE cID = 'K2'), 1), 
('K3', 'S2', 'C', (SELECT cPoints FROM COURSE WHERE cID = 'K3'), 1), 
('K1', 'S3', 'C', (SELECT cPoints FROM COURSE WHERE cID = 'K1'), 1), 
('K2', 'S3', 'E', (SELECT cPoints FROM COURSE WHERE cID = 'K2'), 1), 
('K3', 'S3', 'B', (SELECT cPoints FROM COURSE WHERE cID = 'K3'), 1), 
('K4', 'S3', 'E', (SELECT cPoints FROM COURSE WHERE cID = 'K4'), 2), 
('K5', 'S3', 'D', (SELECT cPoints FROM COURSE WHERE cID = 'K5'), 2)


INSERT INTO Studies (cID, stID, sPoints, termNbr) VALUES 
('K1', 'S1', (SELECT cPoints FROM COURSE WHERE cID = 'K1'), 1), 
('K2', 'S1', (SELECT cPoints FROM COURSE WHERE cID = 'K2'), 1), 
('K3', 'S1', (SELECT cPoints FROM COURSE WHERE cID = 'K3'), 1), 
('K4', 'S2', (SELECT cPoints FROM COURSE WHERE cID = 'K4'), 2), 
('K5', 'S2', (SELECT cPoints FROM COURSE WHERE cID = 'K5'), 2), 
('K6', 'S3', (SELECT cPoints FROM COURSE WHERE cID = 'K6'), 3)

编辑2

我与学生S2进行了另一次测试,共有45分。如果我做HAVING(SUM(wq.sPoints)+(SUM(a.sPoints)))> x)并将x设置为低于50的数字,它会删除学生。如果我将其设置为50及以上,则不会删除学生。所以即使是49人也会删除这名学生。

2 个答案:

答案 0 :(得分:2)

您的查询看起来不错,似乎就像魅力......可能您的数据中有错误?

DECLARE @Studies TABLE(
    cID VARCHAR (5) NOT NULL,
    stID VARCHAR (5) NOT NULL,
    sPoints int,
    termNbr int
)

DECLARE @HasStudied TABLE(
    cID VARCHAR (5) NOT NULL,
    stID VARCHAR (5) NOT NULL,
    grade VARCHAR (5),
    sPoints int,
    termNbr int
)

INSERT INTO @Studies VALUES ('AAA', 'SSS1', 7, 11), ('AAA', 'SSS1', 13, 11), ('AAA', 'SSS1', 30, 11)
INSERT INTO @Studies VALUES ('BBB', 'SSS2', 7, 11), ('BBB', 'SSS2', 13, 11)

INSERT INTO @HasStudied VALUES ('AAA', 'SSS1', 'A', 20, 11), ('BBB', 'SSS2', 'F', 0, 11)

DELETE FROM @Studies
  FROM @Studies a1
  INNER JOIN (SELECT a.stID as ha
                FROM @Studies a 
                INNER JOIN @HasStudied wq ON wq.stID = a.stID 
                WHERE a.stID = 'SSS1' AND a.termNbr = 11 
                GROUP BY a.stID 
                HAVING SUM(wq.sPoints) + SUM(a.sPoints) > 50
              ) a2
     ON a1.stID = a2.ha

SELECT *
  FROM @Studies

结果:

cID stID    sPoints termNbr
BBB SSS2    7       11
BBB SSS2    13      11

答案 1 :(得分:1)

更新

使用Union,您可以获取组合集然后测试总数:

WITH a AS(
    SELECT sPoints 
    FROM Studies
    WHERE termNbr = 2 AND stID = 'S2'
    UNION
    SELECT sPoints 
    FROM HasStudied
    WHERE termNbr = 2 AND stID = 'S2'
)

DELETE FROM Studies
WHERE termNbr = 2 AND stID = 'S2' AND (SELECT SUM(sPoints) FROM a) > 59;

原创

您可以尝试更像这样组织查询,这样可以更轻松地阅读和输入您要查找的参数:

DELETE FROM Studies
WHERE termNbr = 2 AND stID = 'Bob' AND stID IN(
  SELECT s.stID FROM Studies s
  JOIN HasStudied hs ON s.stID = hs.stID AND s.termNbr = hs.termNbr
  WHERE s.termNbr = 2
  GROUP BY s.stID
  HAVING (SUM(s.sPoints) + SUM(hs.sPoints)) > 50
);

http://sqlfiddle.com/#!17/6ffb8/18