我需要帮助找到60列中的平均数,其中列数不等于0

时间:2011-08-11 17:02:25

标签: mysql

我们网站上有2500种产品,分为60个不同类别。我们的数据库方案是61列,标有“product_id”,然后是类别:“category_1”,“category_2”......“category_60”,以及2500行,每个产品一个。如果产品未在特定类别中排名,则该对应字段标记为“0”。如果它被排名,则该字段是具有任何等级的INT:“1”是第一个,“2”是第二个等等。

通常产品仅在2-3个类别中排名,因此在该字段中有57个列具有“0”。我目前的疑问是:

mysql_query("SELECT AVG(category_1 + category_2 + category_3 + category_4 + category_5 + category_6 + category_7 + category_8 + category_9 + category_10 + category_11 + category_12 + category_13 + category_14 + category_15 + category_16 + category_17 + category_18 + category_19 + category_20 + category_21 + category_22 + category_23 + category_24 + category_25 + category_26 + category_27 + category_28 + category_29 + category_30 + category_31 + category_32 + category_33 + category_34 + category_35 + category_36 + category_37 + category_38 + category_39 + category_40 + category_41 + category_42 + category_43 + category_44 + category_45 + category_46 + category_47 + category_48 + category_49 + category_50 + category_51 + category_52 + category_53 + category_54 + category_55 + category_56 + category_57 + category_58 + category_59 + category_60) as 'cat_avg' FROM products.rankings WHERE product_id = '$product_id'");

有了这个,我只是得到了列的总和,而不是AVG。也许这与选择行而不是列有关,我不确定。我也尝试了SUM,而不是AVG,同样的事情。

我不确定从哪里开始。我想要的是一个产品的所有列的平均排名,其中列不等于0.因此,如果product_id 123排名为7,9和11,然后其他57列为0,则返回的平均值为是9((7 + 9 + 11)/ 3),而不是.45((7 + 9 + 11 + 0 + 0 + 0 .... + 0))/ 60)

注意:我没有设计这个数据库,我确信有更好的方法来设计它,但是在这一点上它集成得太深,无法快速更新。

2 个答案:

答案 0 :(得分:1)

这可能会对查询造成很大压力,但鉴于您必须使用的架构,我不知道其他许多方法。

一个选项是子列查询并联合它们,其中给定的列不是0:

SELECT AVG(
  SELECT *
  FROM (
    SELECT category_1 AS category FROM table
    UNION
    SELECT category_2 AS category FROM table
    UNION
    ...
  ) cats
  WHERE category <> 0
)
FROM  products.rankings
WHERE product_id = '$product_id'

在页面(假设PHP给出查询装饰)和每行基础上进行此数学运算可能更有意义。根据我们正在谈论的行数,执行上述操作会给服务器带来很大压力。

答案 1 :(得分:1)

重组整个数据库......虽然没有我那么糟糕,只是做了一堆MySQL查询/更新,让我得到了我需要的东西。使服务器紧张几个小时,但最终还是值得的。