我对MySQL和SQL有点新手,所以希望这不是一个简单的问题。
我有一张桌子,在结账时代表客户购物篮中的物品。此表表示客户仅限于3个项目的情况,因此我目前在购物篮中的每个项目都有一列。它看起来像这样:
+------------------------------------------------------+
+ id | item1 | item2 | item3 | val |
+------------------------------------------------------+
其中val
只是与购物篮相关的一些价值。项目的顺序对我的处理没有任何意义,所以理论上我希望将它们表示为无序集合。这意味着(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)
。
答案 0 :(得分: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
表应该引用item
表中项目的ID,而不是使用项目名称或varchars的描述。