PARTITION BY 多列同时从另一个 table 插入数据

PARTITION BY multiple column while inserting data from another table

如何跳过 SQL 服务器中的唯一约束错误?

这是我的来源table:

CREATE TABLE source 
(
    RollNo INTEGER,
    Nam VARCHAR(6),
    Gender VARCHAR(1),
    Score INTEGER
);
    
INSERT INTO source (RollNo, Nam, Gender, Score)
VALUES ('101', 'John', 'M', '85'),
       ('102', 'Tracy', 'F', '79'),
       ('103', 'Jake', 'M', '92'),
       ('104', 'Edgar', 'M', NULL),
       ('105', 'Monica', 'F', '25'),
       ('106', 'Monica', 'F', '50'),
       ('1070', 'Yash', 'M', '68'),
       ('107', 'Yash', 'M', '70'),
       ('108', 'SFS', 'M', '68'),
       ('18', 'SFS77', 'F', '65');

我想从 source table 填充到 dest table 中,其中 name & Gender 是唯一键并且 SeqNo 应该自动递增:

dest table 描述:

CREATE TABLE dest 
(
    SeqNo BIGINT IDENTITY(1000,1) PRIMARY KEY,
    RollNo INTEGER,
    Nam VARCHAR(6),
    Gender VARCHAR(1),
    Score INTEGER
);

这是我尝试过的:

尝试 #1:

INSERT INTO dest (RollNo, Nam, Gender, Score) 
    SELECT 
        FIRST_VALUE(RollNo) OVER (PARTITION BY Nam, Gender ORDER BY Score DESC),
        FIRST_VALUE(Nam) OVER (PARTITION BY Nam, Gender ORDER BY Score DESC),
        FIRST_VALUE(Gender) OVER (PARTITION BY Nam, Gender ORDER BY Score DESC),
        FIRST_VALUE(Score) OVER (PARTITION BY Nam, Gender ORDER BY Score DESC)
    FROM 
        source 
    WHERE 
        Nam IS NOT NULL AND Gender IS NOT NULL ;

ERROR: Violation of UNIQUE KEY constraint

尝试 #2:

INSERT INTO dest (RollNo, Nam, Gender, Score) 
    SELECT MAX(RollNo),Nam, Gender, MAX(Score) 
    FROM source
    GROUP BY Nam, Gender
    ORDER BY MAX(Score) DESC;

输出:

| SeqNo | RollNo |    Nam | Gender |  Score |
|-------|--------|--------|--------|--------|
|  1000 |    103 |   Jake |      M |     92 |
|  1001 |    101 |   John |      M |     85 |
|  1002 |    102 |  Tracy |      F |     79 |
|  1003 |   1070 |   Yash |      M |     70 |
|  1004 |    108 |    SFS |      M |     68 |
|  1005 |     18 |  SFS77 |      F |     65 |
|  1006 |    106 | Monica |      F |     50 |
|  1007 |    104 |  Edgar |      M | (null) |

如果你看到 yash 行,它占用了最大的 RollNo。和 max of Score 是错误的,我希望它取第一个值,但我不知道该怎么做。

有没有其他方法可以解决exclude这上面两种方法?

您可以使用 ROW_NUMBER() 识别每个 Nam/Gender 元组得分最高的行,并使用该信息过滤源数据:

INSERT INTO dest (RollNo, Nam, Gender, Score) 
SELECT RollNo, Nam, Gender, Score
FROM (
    SELECT s.*,
        ROW_NUMBER() OVER(PARTITION BY Nam, Gender ORDER BY Score DESC) rn
    FROM source s
) s
WHERE rn = 1

旁注:我建议对目标 table 中的 Nam/Gender 元组设置唯一约束,这样在插入时总是会拒​​绝潜在的重复项:

CREATE TABLE dest (
  SeqNo  BIGINT IDENTITY(1000,1) PRIMARY KEY,
  RollNo INTEGER,
  Name   VARCHAR(6),
  Gender VARCHAR(1),
  Score  INTEGER,
  UNIQUE (Name, Gender)
);

旁注 #2:不要在列名两边加上单引号;它们代表标准 SQL.

中的文字字符串