php - 用于计算单列评级的复杂 SQL SELECT

标签 php mysql arrays select

它可能被视为 this 的重复项,但我的问题有点复杂。我有一个包含这些字段的 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 查询不正确,因为它没有显示预期的实际结果。

最佳答案

这个想法是使用子查询来计算总和,然后进行计算并将值放入单个逗号分隔的列中,您可以在 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

关于php - 用于计算单列评级的复杂 SQL SELECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17908099/

相关文章:

mysql utf8 latin,重复键输入失败

mysql - SQL Server如何存储不同客户端的敏感数据?

c - 为什么我的输出没有随着每次循环迭代而改变?

php - Laravel 中的四(或五)向表关系

php - Google Drive SDK 服务帐户错误 "The authenticated user has not installed the app with client id ..."

php - C9 - 如何获取查询结果以及如何从查询中获取行数?

javascript - 比较两个具有相同长度的数组的相同索引

php - 显示带有可选空字段的整个表

PHP Session 安全关键步骤

java - 字符数组的默认值