我们的网站上有 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),而不是 0.45 ((7+9+11+0+0+0....+0))/60)
注意:我没有设计这个数据库,我确信有更好的方法来设计它,但目前它集成得太深,无法快速更改。
最佳答案
这可能会给查询带来很大的压力,但考虑到您必须使用的架构,我不知道还有很多其他方法可以做到这一点。
一种选择是对列进行子查询并将它们联合起来,其中给定的列不为 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 给出了查询修饰)并在每行的基础上进行。执行上述操作会给服务器带来很大的压力,具体取决于我们正在讨论的行数。
关于mysql - 我需要帮助找出 60 列中的平均数,其中列数不等于 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7029951/