MySQL函数:按大多数相似属性排列表

时间:2016-08-07 17:33:33

标签: mysql stored-procedures group-by sql-order-by aggregate-functions

我有products idskeywords的表格,如下所示:

+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_id | int(10) unsigned | YES  | MUL | NULL    |                |
| keyword    | varchar(255)     | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+

此表仅存储产品ID以及与这些产品相关联的关键字。例如,它可能包含:

+----+------------+---------+
| id | product_id | name    |
+----+------------+---------+
|  1 |         1  | soft    |
|  2 |         1  | red     |
|  3 |         1  | leather |
|  4 |         2  | cloth   |
|  5 |         2  | red     |
|  6 |         2  | new     |
|  7 |         3  | soft    |
|  8 |         3  | red     |
|  9 |         4  | blue    |
+----+------------+---------+

换句话说:

  • 产品1是柔软的,红色的和皮革的。
  • 产品2是布料,红色和新品。
  • 产品3红色且柔和,
  • 产品4为蓝色。

我需要一些方法来获取产品ID,并获取按常用关键字数量排序的产品ID排序列表

例如,如果我传入 product_id 1 ,我希望能够回来:

+----+-------+------------+
| product_id | matches    |
+------------+------------+
|     3      | 2          | (product 3 has two common keywords with product 1)
|     2      | 1          | (product 2 has one common keyword with product 1)
|     4      | 0          | (product 4 has no common keywords with product 1)
+------------+------------+

2 个答案:

答案 0 :(得分:1)

一个选项使用带有条件聚合的自右外连接来计算匹配名称的数量,例如:产品ID 1和所有其他产品ID:

SELECT t2.product_id,
       SUM(CASE WHEN t1.name IS NOT NULL THEN 1 ELSE 0 END) AS matches
FROM yourTable t1
RIGHT JOIN yourTable t2
    ON t1.name = t2.name AND
       t1.product_id = 1
WHERE t2.product_id <> 1
GROUP BY t2.product_id
ORDER BY t2.product_id

请按照以下链接查看正在运行的演示:

SQLFiddle

答案 1 :(得分:1)

outer join keywordsproductid 1使用select y.productid, count(y2.keyword) from yourtable y left join ( select keyword from yourtable y2 where y2.productid = 1 ) y2 on y.keyword = y2.keyword where y.productid <> 1 group by y.productid order by 2 desc

| productid | count(y2.keyword) |
|-----------|-------------------|
|         3 |                 2 |
|         2 |                 1 |
|         4 |                 0 |

结果:

{{1}}