如何根据SQL / PHP中的列值找到相似的行

时间:2015-09-01 18:45:27

标签: php mysql sql

我正在建立一个电子商务电脑商店,并将所有产品的规格存储为列(因此RAM,处理器,颜色,品牌等都是不同的列)
我已经建立了搜索以查找产品并将其链接到人们可以查看产品的页面以及有关它的所有信息。
当有人查看产品时,我想要一个类似产品的部分"。
它应该根据不同列的值获得这些产品并获得最佳匹配

比如说我在这里有产品表:

+----+------+--------+-------+--------+--------+
| id | Name |  Type  | Brand | Colour | Memory |
+----+------+--------+-------+--------+--------+
| 1  | Name1| laptop |  Asus | White  |  2GB   |
| 2  | Name2| laptop |  Acer |  Red   |  4GB   | 
| 3  | Name3|computer|   Hp  |  Blue  |  3GB   | 
| 4  | Name4| laptop |  Acer |  White |  6GB   | 
| 5  | Name5| laptop |   HP  |  Red   |  4GB   | 
+----+------+--------+-------+--------+--------+

让我们说用户正在查看产品ID 1 那么按顺序,最好的匹配将是:

+----+------+--------+-------+--------+--------+
| id | Name |  Type  | Brand | Colour | Memory |
+----+------+--------+-------+--------+--------+
| 4  | Name4| laptop |  Acer | White  |  6GB   |
| 2  | Name2| laptop |  Acer |  Red   |  4GB   | 
| 5  | Name5| laptop |   Hp  |  Red   |  4GB   | 
| 3  | Name3|computer|   HP  |  Blue  |  3GB   | 
+----+------+--------+-------+--------+--------+

所以我想,简而言之,我要问的是,我将如何选择具有最匹配列的所有行,按照它与当前行匹配的列数

1 个答案:

答案 0 :(得分:1)

您可以比较感兴趣的项目与剩余项目集合之间的相同列数,并按匹配数量的总和进行排序。

如果要优先考虑某些属性,可以更改算术以包含权重。因此,例如,可以将计算结果为1或0的布尔表达式t1.Memory = t2.Memory更改为使用内存中差异的绝对值来获得最接近的匹配。等等。

请注意,此查询使用固定属性并假定没有空值 - 如果可以存在空值(例如,使用coalesce),您还可以使用动态sql来计算要比较的不同数量的属性。

此外,并非所有数据库都可以评估像t1.Memory = t2.Memory这样的布尔表达式(MySQL可以),它实际上是case when t1.Memory = t2.Memory then 1 else 0 end的简短形式

select 
    t1.*
    , sum(t1.type = t2.type) 
    + sum(t1.Brand = t2.Brand) 
    + sum(t1.Colour = t2.Colour)  
    + sum(t1.Memory = t2.Memory) as commonality
from products  t1, products  t2 
where t2.id = 1 and t1.id <> t2.id
group by t1.id, t1.Name, t1.Type, t1.Brand, t1.Colour, t1.Memory
order by 
  sum(t1.type = t2.type) 
  + sum(t1.Brand = t2.Brand) 
  + sum(t1.Colour = t2.Colour) 
  + sum(t1.Memory = t2.Memory) desc, Brand

Sample SQL Fiddle

将样本数据和ID 1作为要与结果进行比较的项目将是:

| id |  Name |     Type | Brand | Colour | Memory | commonality |
|----|-------|----------|-------|--------|--------|-------------|
|  4 | Name4 |   laptop |  Acer |  White |    6GB |           2 |
|  2 | Name2 |   laptop |  Acer |    Red |    4GB |           1 |
|  5 | Name5 |   laptop |    HP |    Red |    4GB |           1 |
|  3 | Name3 | computer |    Hp |   Blue |    3GB |           0 |