检查mysql中是否存在组合(按时间戳分组)

时间:2015-01-12 21:53:20

标签: mysql database group-concat

Fiddle Example

我有一个页面,允许人们比较数据库中的项目。每次比较的项目数量不固定。我使用两列表来存储他们的比较记录和时间戳,作为将它们组合在一起的方法。

假设我有product_id 304308以及306,我如何检查它们是否作为同一组存在于数据库中?我不确定如何检查多个product_ids的组合,我正在寻找类似的东西:

输出:

product_id    name
306|308|304   D|E|C

以下是查询:

SELECT product_id,name
FROM (
   SELECT 
   GROUP_CONCAT(c.product_id SEPARATOR "|") AS product_id,
   GROUP_CONCAT(p.name SEPARATOR "|") AS name
  FROM compare c
  INNER JOIN product p ON p.product_id = c.product_id
  GROUP BY c.timestamp
  ORDER BY c.timestamp
  /* How to do a where clause here? WHERE p.product_id = 306 AND p.product_id = 308 AND p.product_id = 304 */
  )e
GROUP BY product_id


CREATE TABLE compare
    (`product_id` int,`timestamp` timestamp)
;

INSERT INTO compare
    (`product_id`,`timestamp`)
VALUES
    (300,'2015-01-12 19:04:13'),
    (302,'2015-01-12 19:04:13'),
    (304,'2015-01-12 19:06:24'),
    (306,'2015-01-12 19:06:24'),
    (308,'2015-01-12 19:06:24'),
    (310,'2015-01-12 19:08:40'),
    (312,'2015-01-12 19:08:40'),
    (314,'2015-01-12 19:08:40'),
    (316,'2015-01-12 19:08:40'),
    (302,'2015-01-12 19:10:50'),
    (316,'2015-01-12 19:10:50')

;

CREATE TABLE product
    (`product_id` int,`name` varchar(30))
;

INSERT INTO product
    (`product_id`,`name`)
VALUES
    (300,'A'),
    (302,'B'),
    (304,'C'),
    (306,'D'),
    (308,'E'),
    (310,'F'),
    (312,'G'),
    (314,'H'),
    (316,'I')

;

1 个答案:

答案 0 :(得分:1)

如果我的意图是正确的,你想要保留一份比较列表,并且如果发生某种比较就能回答问题,并且可能会对此列表进行重复数据删除。

你的方法不起作用。

您需要的是有效地将product_ids设置为某个标识符。这是可能的方法之一:

CREATE TABLE comparison (
    id int not null auto_increment,
    created_at timestamp default current_timestamp,
    hash varchar(16), -- or some other type depending the hash function of your choice
    primary key (id),
    key (hash)
);

CREATE TABLE comparison item (
    comparison_id int not null,
    product_id int not null,
    primary key (comparison_id, product_id)
);

在创建新比较(或检查是否已存在)时,您计算product_ids集的哈希函数,比如说你对product_ids进行排序,连接它们,得到结果的md5并以十六进制表示存储一半字符串(它更短,但仍然足够。)

如果要检查已存储的比较,首先要检查是否存在具有给定哈希的记录。

如果是,那么您可以使用相应的comparison_id从第二个表中获取所有行,以确保您没有幸运地遇到冲突。

如果没有,这意味着你以前从未遇到过这个集。

使用此结构,您仍然可以在创建比较时存储时间戳,并检查是否曾使用过单个product_id(为此,您需要在第二个表中另外添加key(product_id)