【问题标题】:PARTITION BY multiple column while inserting data from another tablePARTITION BY 多列同时从另一个表插入数据
【发布时间】:2021-03-29 20:38:06
【问题描述】:

如何在 SQL Server 中跳过唯一约束错误?

这是我的源表:

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 表中填充dest 表,其中nameGender 是唯一键,SeqNo 应该自动递增:

dest表说明:

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 ;

错误:违反 UNIQUE KEY 约束

尝试 #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。和最大的分数是错误的,我希望它取第一个值,但我不知道该怎么做。

排除以上两种方法,有没有其他方法可以解决?

【问题讨论】:

  • 几天前你还在使用 MySQL。您真的确定您使用的是 SQL Server 吗?它们有不同的语法规则。

标签: sql sql-server sql-insert greatest-n-per-group


【解决方案1】:

您可以使用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

旁注:我建议对目标表中的 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 中的文字字符串。

【讨论】:

  • 感谢您的帮助。实际上我是 SQL 方面的新手。它按预期工作,但我必须删除 s.*.你能解释一下为什么吗? http://sqlfiddle.com/#!18/2a1ec/1
  • @HarshitMahajan:缺少表别名。固定。
猜你喜欢
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多