【问题标题】:How to create a PK by summing a column value and a self-increasing如何通过对列值和自增求和来创建 PK
【发布时间】:2026-02-15 14:45:01
【问题描述】:

我正在处理 ETL,我需要创建一个新表。此表在源中没有 PK,因此我必须在我的 Staging 中创建它。

这是我从中提取数据的查询:

SELECT PP.PRVECODI,
       VW.GRUPDESC,
       VW.FAMIDESC,
       PP.ARTICODI,
       VW.ARTIDESC,
       PP.PROVREFER,
       PP.PPLNMARCA,
       PP.PPLNORIGEN,
       ( SELECT COUNT(1)
         FROM   CPR05.ACUERDOSCOMPRA AC
         WHERE AC.ARTICODI = VW.ARTICODI
         AND   AC.ACUCDESDE <= TRUNC(SYSDATE)
         AND   AC.ACUCHASTA >= TRUNC(SYSDATE)
         AND AC.PRVECODI = PP.PRVECODI ) ACUERDOS,VW.SBFMDESC
FROM   CPR05.SAC_VWARTICULOS VW
       INNER JOIN (
         SELECT DISTINCT
                ARTICODI,
                PL.PROVREFER,
                PL.PPLNMARCA,
                PL.PPLNORIGEN,
                P.PRVECODI
         FROM   CPR05.PROPUESTASLINEAS PL 
                INNER JOIN CPR05.PROPUESTAS P
                ON (P.PPTACODI = PL.PPTACODI)
                   AND P.PPTAFECFIN >= TRUNC(SYSDATE)
       ) PP
       ON (VW.ARTICODI=PP.ARTICODI)
ORDER BY
       VW.GRUPDESC,
       VW.FAMIDESC,
       VW.ARTIDESC

我需要创建一个表来插入这个查询并且PK必须是PP.ARTICODI列和一个自增整数的组合。

我尝试将标识列与 ARTICODI 结合,但它不起作用:

CREATE TABLE CENTRALCOMPRASSTG..ProveedoresCatalogo(
  IDProveedoresCatalogo INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
  PRVECODI NUMERIC(9,0),
  GRUPDESC NVARCHAR(40),
  FAMIDESC NVARCHAR(40),
  ARTICODI NUMERIC(9,0),
  PROVREFER NVARCHAR(20),
  PPLNMARCA NVARCHAR(20),
  PPLNORIGEN NVARCHAR(50),
  ACUERDOS INT,
  SBFMDESC NVARCHAR(40)
)

Expected output 提前致谢

【问题讨论】:

  • 如果您询问如何拥有一个由另一列分区或基于另一列分区的IDENTITY 列(因此您可以为不同的1 值设置两个1 值),那么您不能不支持。如果您要问其他问题,那么您的问题不清楚,您应该 edit 它提供 minimal reproducible example 显示您的预期输入和结果。
  • 主键可以由多个列组成,如果您的意思是这样的话,可能
  • @nikos-m 在这种情况下我不需要约束 pk,而是自动增量整数和当前列的组合,请检查预期输出
  • @MT0 抱歉,已编辑
  • 您的代码真的要在 Oracle 数据库上使用吗?它使用 IDENTITY 和内联 PRIMARY KEY 约束的方式使其看起来像 SQL Server(尽管您已将帖子标记为 Oracle)

标签: sql sql-server ssis etl


【解决方案1】:

在 Oracle 12c 及更高版本中,您可以使用 IDENTITY 列生成唯一值,然后使用虚拟列将其与 ARTICODI 列组合:

CREATE TABLE ProveedoresCatalogo (
  IDProveedoresCatalogo INT
                        GENERATED ALWAYS AS IDENTITY(
                                              START WITH   1000000
                                              INCREMENT BY 1000000
                                            )
                        PRIMARY KEY
                        NOT NULL,
  ExpectedPK            INT
                        GENERATED ALWAYS AS ( IDProveedoresCatalogo + ARTICODI )
                        UNIQUE,
  ARTICODI              NUMBER(6,0) NOT NULL, -- Ensure this is only 6 digits
  PRVECODI              NUMBER(9,0),
  GRUPDESC              NVARCHAR2(40),
  FAMIDESC              NVARCHAR2(40),
  PROVREFER             NVARCHAR2(20),
  PPLNMARCA             NVARCHAR2(20),
  PPLNORIGEN            NVARCHAR2(50),
  ACUERDOS              INT,
  SBFMDESC              NVARCHAR2(40)
)

那么,如果你:

INSERT INTO ProveedoresCatalogo ( ARTICODI, PRVECODI )
SELECT 700002, 13757 FROM DUAL UNION ALL
SELECT 700002, 10561 FROM DUAL UNION ALL
SELECT 700002, 51212 FROM DUAL;

然后:

SELECT IDProveedoresCatalogo,
       ExpectedPK,
       ARTICODI,
       PRVECODI
FROM   ProveedoresCatalogo

输出:

IDPROVEEDORESCATALOGO |预期PK |青蒿 | PRVECODI --------------------: | ---------: | --------: | --------: 1000000 | 1700002 | 700002 | 13757 2000000 | 2700002 | 700002 | 10561 3000000 | 3700002 | 700002 | 51212

db小提琴here


在 SQL Server 中:

CREATE TABLE ProveedoresCatalogo (
  IDProveedoresCatalogo INT
                        IDENTITY( 1000000, 1000000 )
                        PRIMARY KEY
                        NOT NULL,
  ExpectedPK            AS ( IDProveedoresCatalogo + ARTICODI )
                        UNIQUE,
  ARTICODI              NUMERIC(6,0) NOT NULL, -- Ensure this is only 6 digits
  PRVECODI              NUMERIC(9,0),
  GRUPDESC              NVARCHAR(40),
  FAMIDESC              NVARCHAR(40),
  PROVREFER             NVARCHAR(20),
  PPLNMARCA             NVARCHAR(20),
  PPLNORIGEN            NVARCHAR(50),
  ACUERDOS              INT,
  SBFMDESC              NVARCHAR(40)
)

db小提琴here

【讨论】:

  • SQL-Server 中有没有等价的?
  • @ToniCuc 更新
  • 我想我在尝试创建一个将增量和 ARTICODI 组合的字段时被混淆了,而最简单的解决方案可能是使用增量和 ARTICODI 作为约束 pk
【解决方案2】:

您可以为此使用计算列:

CREATE TABLE CENTRALCOMPRASSTG..ProveedoresCatalogo(
  InternalIdentityID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
  IDProveedoresCatalogo = CAST(CONCAT(InternalIdentityID, ARTICODI) AS INT),
  PRVECODI NUMERIC(9,0),
  GRUPDESC NVARCHAR(40),
  FAMIDESC NVARCHAR(40),
  ARTICODI NUMERIC(9,0),
  PROVREFER NVARCHAR(20),
  PPLNMARCA NVARCHAR(20),
  PPLNORIGEN NVARCHAR(50),
  ACUERDOS INT,
  SBFMDESC NVARCHAR(40)
)

或者(也许这个更快):

CREATE TABLE CENTRALCOMPRASSTG..ProveedoresCatalogo(
  InternalIdentityID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
  IDProveedoresCatalogo = InternalIdentityID * POWER(10, LEN(ARTICODI)) + ARTICODI,
(...)

【讨论】:

  • SQL-Server 中有没有等价的?
  • 如果您使用CONCAT( 1, 7102 )CONCAT( 17, 102 ),这可能会产生问题。
  • @MT0 肯定会。但这基本上是要求![i.stack.imgur.com/V1ue1.png]
最近更新 更多