Php 用于从集合列中获取最常用项的SQL查询
我们在mysql数据库中有一个用户配置文件表,其中一个字段是跟踪用户组的Php 用于从集合列中获取最常用项的SQL查询,php,mysql,sql,zend-framework,Php,Mysql,Sql,Zend Framework,我们在mysql数据库中有一个用户配置文件表,其中一个字段是跟踪用户组的SET列 表格结构为: CREATE TABLE IF NOT EXISTS `users_profiles` ( `userId` mediumint(9) NOT NULL DEFAULT '0', `birthday` date DEFAULT NULL, `groups` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','1
SET
列
表格结构为:
CREATE TABLE IF NOT EXISTS `users_profiles` (
`userId` mediumint(9) NOT NULL DEFAULT '0',
`birthday` date DEFAULT NULL,
`groups` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20')
);
我想在一个排序的降序列表中得到最受欢迎的组,但是我们使用了集合
列,这使得使用计数
等函数有点困难
通过运行此查询,我可以获得特定的组计数:
SELECT count(NULLIF(`interests` & 1,0)) as Count1stVal FROM users_profiles;
但是,我不想为每个组运行查询,然后计算最流行的组我有一个建议,但不是实际的代码(因为我不太熟悉集合数据类型) 首先,创建一个临时表或子查询,其中集合的每个元素都有一行。每一行在其集合中正好有该元素。称之为元素 其次,执行以下查询:
select e.element, count(*)
from user_profiles up join
Elements e
on up.groups like concat('%', e.element, '%')
group by e.element
order by 2 desc
现在,唯一的问题是设置的值彼此重叠。所以,你有“1”和“10”,所以这不太管用。您可以执行以下操作之一来修复此问题
该页面很好地概述了如何使用集合。这也解释了为什么他们经常感到沮丧。因为它们不提供规范化表的功能。类似的功能应该可以:
SELECT
groups, # get the group number
COUNT(groups) AS group_cnt # use this for sorting
FROM users_profiles
GROUP BY groups
ORDER BY group_cnt DESC
我没有服务器在这台机器上,所以我不能测试它,但我认为它应该工作的预期
编辑:仅当“组”列中只有一个值时,查询才起作用
如果您有一个不同的表,其中组将作为条目列出,id与集合中的数字对应,您可以执行以下操作:
SELECT
g.id, # the group id corresponds to the groups in the set
COUNT(up.userId) as g_cnt # count the number of users with the group
FROM (
users_profiles up,
groups g
)
WHERE
FIND_IN_SET(g.id, up.groups) > 0
GROUP BY g.id
ORDER BY g_cnt DESC
但是如果您要引入一个groups表,那么最好将其规范化为用户和组之间的多对多关系为什么这会变得困难?应该没什么区别。也许你应该添加你迄今为止尝试过的内容,以便更清楚地知道你在哪里遇到了障碍。也许这就是你要找的,还有GROUP BY。或者只是分组和计数(groups)。你应该从你的问题中得出一个结论,那就是数据结构不可能正常化吗?我试过了,但它是根据列的值来计数组的,列是由许多组组成的(这意味着它实际上是计数不同组的集合),你说的是什么“根据列的值对组进行计数”,因为我刚刚测试了这个功能,它可以工作。它可以为我提供从最常见到最罕见的组的组数和计数顺序。如果列是
枚举
,您的解决方案可能会工作。当我运行查询时,我会得到混合组的结果,例如“1,2,20”“是的,集合可以有多个值,这将导致我的第一个查询无法使用,这是我不知道的。无论如何,我已经编辑了回复,写下了在这种情况下我会做什么,因为这是一个有点多的评论感谢链接。虽然帮助不大,但我仍在寻找解决方案。数值是个问题,所以使用字符串CONCAT
对我来说不起作用