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

check if combinations (Group by timestamp) exist in mysql

Fiddle Example

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

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

输出:

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')

;

如果我理解你的意图,你希望维护一个比较列表,并能够在某个比较发生时回答问题,并且可能会删除该列表的重复数据。

你的方法行不通。

您需要的是有一种有效的方法将您的 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并以十六进制形式存储一半的字符串(它更短但仍然足够)。

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

如果是,那么您可以从第二个 table 中获取所有具有相应 comparison_id 的行,以确保您不会幸运地遇到碰撞。

如果没有,说明你没有遇到过这一套

使用此结构,您仍然可以在创建比较时存储时间戳,并检查是否曾使用过某个 product_id(为此,您需要在第二个 [=33] 中添加一个额外的 key(product_id) =]).