如何通过对列值和自增求和来创建PK

How to create a PK by summing a column value and a self-increasing

我正在处理 ETL,我需要创建一个新的 table。此 table 在源代码中没有 PK,因此我必须在我的暂存中创建它。

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

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

我需要创建一个Table来插入这个查询,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 提前致谢

您可以为此使用计算列:

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,
(...)

在 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 | EXPECTEDPK | ARTICODI | PRVECODI
--------------------: | ---------: | -------: | -------:
              1000000 |    1700002 |   700002 |    13757
              2000000 |    2700002 |   700002 |    10561
              3000000 |    3700002 |   700002 |    51212

db<>fiddle here


在 SQL 服务器中:

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<>fiddle here