Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 用于从集合列中获取最常用项的SQL查询_Php_Mysql_Sql_Zend Framework - Fatal编程技术网

Php 用于从集合列中获取最常用项的SQL查询

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

我们在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','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”,所以这不太管用。您可以执行以下操作之一来修复此问题

  • 重命名设置的值(例如,实际表可能没有此问题)
  • 使用“&”操作和生成的数字列表。在这种情况下,on语句更改为:

    在up.groups&e.element>0时


  • 该页面很好地概述了如何使用集合。这也解释了为什么他们经常感到沮丧。因为它们不提供规范化表的功能。

    类似的功能应该可以:

    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
    对我来说不起作用