0

它可能被认为是重复的但我的问题有点复杂。我有一个包含这些字段的 MySQL 表:

ip | product_id | visits

它显示了一个 ip 访问过产品的次数。我终于想生成一个这样的php数组:

product_rating_for_ip = array(
  ip=>array(
    product_id=>rating, product_id=>rating, ...
  ),
  ip=>array(
    product_id=>rating, product_id=>rating, ...
  ),
  .
  .
  .
);

评级等于来自某个 ip 的单个产品的访问量除以该 ip 的所有产品访问量的 MAX。例如:

product_rating_for_ip = array(
  "78.125.15.92"=>array(
    1=>0.8,2=>0.2,3=>1.0
  ),
  "163.56.75.112"=>array(
    1=>0.1,2=>0.3,3=>0.5,8=>0.1,12=>1.0
  ),
  .
  .
  .
);

我做了什么 :

SELECT ip, id, visits, MAX(visits) FROM visit GROUP BY ip

我有性能考虑,我想避免嵌套循环中的 SQL 查询。我认为上面的 SQL 查询是不正确的,因为它没有显示预期的实际结果。

4

1 回答 1

1

这个想法是使用子查询来计算总和,然后进行计算并将值放入一个逗号分隔的列中,您可以将其转换为 php 中的数组:

select v.ip, group_concat(v.visits / iv.maxvisits) as ratings
from visit v join
     (SELECT ip, id, visits, max(visits) as maxvisits
      FROM visit
      GROUP BY ip
     ) iv
     on v.ip = iv.ip
group by v.ip;

编辑:

SQL 中的表本质上是无序的,并且 SQL 中的排序是不稳定的(意味着不保留原始顺序)。group_concat()您可以在语句中指定排序。例如,以下将按以下顺序排列结果id

select v.ip, group_concat(v.visits / iv.maxvisits order by id) as ratings
from visit v join
     (SELECT ip, id, visits, max(visits) as maxvisits
      FROM visit
      GROUP BY ip
     ) iv
     on v.ip = iv.ip
group by v.ip;

这将首先按最高评级排序:

select v.ip, group_concat(v.visits / iv.maxvisits order by v.visits desc) as ratings

您可以使列表更复杂以包含id在其中:

select v.ip,
      group_concat(concat(v.id, ':', v.visits / iv.maxvisits)) as ratings
于 2013-07-28T12:26:55.663 回答