【问题标题】:Duplicate Entry for Primary Key主键重复输入
【发布时间】:2019-10-04 06:58:40
【问题描述】:

给出的任务是:

创建一个新的关系表来存储有关所有供应商的公司名称和每个供应商提供的产品总数的信息。在新表上执行适当的一致性约束。接下来,将所有供应商的公司名称和每个供应商提供的产品总数的信息复制到新表中。

当我尝试运行此脚本时,我收到错误 Duplicate Entry for key "PRIMARY"


     CREATE TABLE COMPANY_AND_SUPPLIERS (

        COMPANY_NAME VARCHAR (40) NOT NULL DEFAULT 'EMPTY',
        PRODUCT_NAME VARCHAR(40) NOT NULL DEFAULT 'EMPTY' ,
        TOTAL_PRODUCTS VARCHAR(40) NOT NULL DEFAULT 'EMPTY',
        CONSTRAINT SUPPLIER_PKEY PRIMARY KEY(COMPANY_NAME) ,
        CONSTRAINT SUPPLIER_FKEY FOREIGN KEY (COMPANY_NAME) REFERENCES SUPPLIER(COMPANY_NAME)


        );

    INSERT INTO COMPANY_AND_SUPPLIERS(COMPANY_NAME, PRODUCT_NAME)
    SELECT  DISTINCT SUPPLIER.COMPANY_NAME, PRODUCT.PRODUCT_NAME
    FROM SUPPLIER, PRODUCT;

    UPDATE COMPANY_AND_SUPPLIERS
    SET TOTAL_PRODUCTS = (SELECT COUNT(*) AS TOTALPRODUCTS
    FROM PRODUCT);

整个练习的目的是复制所有供应商的公司名称和每个供应商提供的产品总数。

给出的表格

CREATE TABLE SUPPLIER
(
    COMPANY_NAME    VARCHAR(40) NOT NULL,
    CONTACT_NAME    VARCHAR(30),
    CONTACT_TITLE   VARCHAR(30),
    ADDRESS         VARCHAR(60),
    CITY        VARCHAR(15),
    REGION      VARCHAR(15),
    POSTAL_CODE     VARCHAR(10),
    COUNTRY         VARCHAR(15),
    PHONE       VARCHAR(24),
    FAX         VARCHAR(24),
    HOME_PAGE       VARCHAR(500),
    CONSTRAINT PK_SUPPLIER PRIMARY KEY (COMPANY_NAME)  
);

CREATE TABLE PRODUCT
(
    PRODUCT_NAME    VARCHAR(40)     NOT NULL,
    SUPPLIER_NAME   VARCHAR(40)     NOT NULL,
    CATEGORY_NAME   VARCHAR(30) NOT NULL,
    QUANTITY_PER_UNIT   VARCHAR(20),
    UNIT_PRICE      DECIMAL(10,2)   NOT NULL    DEFAULT 0,
    UNITS_IN_STOCK  DECIMAL(9)  NOT NULL    DEFAULT 0,
    UNITS_ON_ORDER  DECIMAL(9)  NOT NULL    DEFAULT 0, 
    REORDER_LEVEL   DECIMAL(9)  NOT NULL    DEFAULT 0,
    DISCONTINUED    CHAR(1)     NOT NULL    DEFAULT 'N',
    CONSTRAINT PK_PRODUCT PRIMARY KEY (PRODUCT_NAME),
    CONSTRAINT FK_CATEGORY_NAME FOREIGN KEY (CATEGORY_NAME) REFERENCES CATEGORY(CATEGORY_NAME),
    CONSTRAINT FK_SUPPLIER_NAME FOREIGN KEY (SUPPLIER_NAME) REFERENCES SUPPLIER(COMPANY_NAME),
    CONSTRAINT CK_PRODUCT_UNIT_PRICE CHECK (UNIT_PRICE >= 0),
    CONSTRAINT CK_PRODUCT_UNITS_IN_STOCK CHECK (UNITS_IN_STOCK >= 0),
    CONSTRAINT CK_PRODUCT_UNITS_ON_ORDER CHECK (UNITS_ON_ORDER >= 0),
    CONSTRAINT CK_PRODUCT_REORDER_LEVEL CHECK (REORDER_LEVEL >= 0),
    CONSTRAINT CK_PRODUCT_DISCONTINUED CHECK (DISCONTINUED in ('Y','N'))
);

【问题讨论】:

  • 哦,确实如此。它产生不同的行,而不是不同的COMPANY_NAME。重新审视您的解决方案。
  • @TheImpaler 没有重复项有区别吗?
  • 那么每个供应商都可以供应每种产品吗?这就是INSERT 语句对SUPPLIER, PRODUCT 的作用。它的命名也很奇怪,其中 TOTAL_PRODUCTS 是所有产品的总和。为什么 TOTAL_PRODUCTS 是 VARCHAR 而不是数字类型。如果不需要填充表值,建议使用“NULL”,而不是默认字符串“EMPTY”。
  • @danblack 是的,许多供应商可以供应许多产品。关于空默认值,如果我不这样做,则表示它们需要默认值。
  • 主键应该是复合(COMPANY_NAME, PRODUCT_NAME),以允许公司销售多种产品。

标签: mysql


【解决方案1】:

company_name 列不应是 primary key,因为 primary key 是唯一值。

以此为例

如果数据库管理员创建一个以first_name 作为主键的表,那将是一场灾难,因为有很多人以 John 作为他们的名字

这就是为什么大多数时候,主键是一个整数,然后我们使用this方法使其唯一。

【讨论】:

    【解决方案2】:

    您的表格不应包含产品名称,而应包含公司和总产品。 PRODUCTS 表中已经包含每个产品的供应商名称。因此,您只需计算该表中每个供应商的产品数量。

    CREATE TABLE Company_Totals (
        Company_name VARCHAR(40) NOT NULL,
        Total_Products INT(11) NOT NULL,
        PRIMARY KEY (Company_name),
        FOREIGN KEY (Company_name) REFERENCES Supplier(Company_name)
    );
    
    INSERT INTO Company_Totals (Company_name, Total_Products)
    SELECT SUPPLIER_NAME, COUNT(*)
    FROM PRODUCT
    GROUP BY SUPPLIER_NAME;
    

    【讨论】:

    • 是的,他们给了我们一个产品表和一个供应商表。产品表没有公司名称,但供应商表有。 @Barmar
    • 我尝试进行您的查询,但所有产品的总数为 1。 @Barmar
    • 他们需要给你第三张表来链接产品和供应商。
    • 请看我的编辑我添加了给定@Barmar的两个表格
    • 给你的PRODUCT 表就是我说的表。它有公司名称和产品名称。
    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多