2

一般来说,我对 MySQL 和 SQL 有点陌生,所以希望这不是一个简单的问题。

我有一张表格,在结账时代表客户购物篮中的物品。此表表示客户仅限于 3 件商品的情况,因此我目前在购物篮中的每件商品都有一列。它看起来像这样:

+------------------------------------------------------+
+   id   |   item1   |   item2   |   item3   |   val   |
+------------------------------------------------------+

whereval只是与篮子相关的一些值。就我的处理而言,项目的排序没有任何意义,所以理论上我希望将它们表示为无序集。这意味着一行 在(i1,i2,i3,val)功能上等同于(i2,i1,i3,val)

我的问题是,如何在我的表和/或 SQL 中实现这一点,以便选择(i3,i2,i1,val)将返回该行(i1,i2,i3,val)

当我插入时,我还需要有一些能捕捉到独特性的东西。例如,如果我插入(i2,i3,i1,newval),我希望表更新(i1,i2,i3,val)(i1,i2,i3,newval)

4

1 回答 1

0

您可以通过使用客户和项目之间的 0 到多关系来标准化您的模型:

-- assuming the existing table to be named `yourtable`
-- assuming your customer's table to be named `customer`
-- assuming your customer's id in the customer's table to be named `id`
-- assuming innodb (remove fk constraint if not)

CREATE TABLE `customer_item` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `id_customer` INT(10) NOT NULL, 
    `item` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`id`)
)
ENGINE=innodb
SELECT NULL AS `id`, t.id AS `id_customer`, t.`item`
FROM (
    SELECT id, item1 AS `item`
    FROM
        yourtable
    UNION
    SELECT id, item2 AS `item`
    FROM
        yourtable
    UNION
    SELECT id, item3 AS `item`
    FROM
        yourtable
) t
ORDER BY t.id ASC
;

CREATE INDEX UNIQUE `idx_customer_item_cust` ON `customer_item` (`id_customer`, `item`);
ALTER TABLE `customer_item` ADD CONSTRAINT `fk_customer_item_cust` FOREIGN KEY (`id_customer`) REFERENCES `customer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;


-- once you check the data is consistent:

DROP TABLE `yourtable`;

一旦完成,就不可能为同一个客户插入两次。请注意:

  • 联合选择在创建表时跳过重复项,以防某些客户重复某些项目
  • 从客户到项目的角度,您的数据已标准化
  • 从项目的角度来看,您的数据仍未标准化。您应该有一个项目表,并且该customer_item表应该引用表中项目的 id,item而不是使用项目名称或 varchars 的描述。
于 2013-11-11T18:39:49.780 回答