Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.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 如何计算MySQL中的唯一集值_Php_Mysql_Mysqli - Fatal编程技术网

Php 如何计算MySQL中的唯一集值

Php 如何计算MySQL中的唯一集值,php,mysql,mysqli,Php,Mysql,Mysqli,如果您能帮助我计算MySql中集合类型的唯一值,我将不胜感激。我将一个名为features的列定义为集合字段,如下所示: CREATE TABLE cars (features SET('power steering', 'power locks', 'satellite radio', 'power windows', 'sat nav', 'turbo')); 当我填写此表时,由于这些特性不是互斥的,因此我将得到包含两个或更多这些特性组合的记录。例如: 1号车有动力转向和电动车窗,但没有其

如果您能帮助我计算MySql中集合类型的唯一值,我将不胜感激。我将一个名为features的列定义为集合字段,如下所示:

CREATE TABLE cars (features SET('power steering', 'power locks', 'satellite radio', 'power windows', 'sat nav', 'turbo'));
当我填写此表时,由于这些特性不是互斥的,因此我将得到包含两个或更多这些特性组合的记录。例如:

1号车有动力转向和电动车窗,但没有其他功能。 2号车具备所有功能。 除卫星导航和涡轮外,3号车拥有所有功能

我想做的是获得表中所有单个列出的功能的列表,包括以类似于使用GROUPBY子句的SELECT语句的方式关联到每个功能的记录计数。因此,按照上面的例子,我应该能够得到以下结果:

features       |count
---------------+------
power steering | 3      //All cars have this feature
power locks    | 2      //Only cars 2 and 3 have it
satellite radio| 2      //Only cars 2 and 3 have it
power windows  | 3
sat nav        | 1      //only car 2 has it
turbo          | 1      //only car 2 has it
我尝试使用以下查询,期望获得上述结果:

SELECT features, COUNT(features) FROM cars GROUP BY features;
 SELECT f.feature
      , COUNT(1)
   FROM ( SELECT 'power steering' AS feature
          UNION ALL SELECT 'power locks' 
          UNION ALL SELECT 'satellite radio'
          UNION ALL SELECT 'power windows'
          UNION ALL SELECT 'sat nav'
          UNION ALL SELECT 'turbo'
        ) f
  JOIN cars c
    ON FIND_IN_SET(f.feature,c.features)>0
 GROUP BY f.feature
 ORDER BY f.feature
但是,我得到的不是我所期望的,而是每个现有功能组合的计数:

features                                        |count
------------------------------------------------+--------
power steering, power windows                   | 1 //i.e. only 1 car has                 
                                                |   //only these 2 features
                                                |   //(car 1 in this example)
                                                |   
------------------------------------------------+-------
power steering, power locks, satellite radio,   |
power windows, sat nav, turbo                   | 1
------------------------------------------------+-------
power steering, power locks, satellite radio,   |
power windows                                   | 1
所以,问题是:有没有一种方法可以使用一个MySQL查询获得第一个表中所示的每个特性的计数?我可以通过对每个特性执行一个查询来实现这一点,但我相信一定有办法避免这种麻烦。有人可能会建议使用不同的表进行特性和连接,但此时不可能不严重影响项目的其余部分。提前谢谢

通常,我们使用FIND_IN_SET函数

您可以使用如下查询返回指定的结果:

SELECT features, COUNT(features) FROM cars GROUP BY features;
 SELECT f.feature
      , COUNT(1)
   FROM ( SELECT 'power steering' AS feature
          UNION ALL SELECT 'power locks' 
          UNION ALL SELECT 'satellite radio'
          UNION ALL SELECT 'power windows'
          UNION ALL SELECT 'sat nav'
          UNION ALL SELECT 'turbo'
        ) f
  JOIN cars c
    ON FIND_IN_SET(f.feature,c.features)>0
 GROUP BY f.feature
 ORDER BY f.feature
您可以忽略>0并获得相同的结果。此查询忽略零计数:具有任何汽车都不会显示的功能的行。要获得这些,您可以使用外部联接在联接之前添加LEFT关键字,而不是选择列表中的COUNT1、COUNTexpr,其中expr是cars中不为NULL的列,或者在找到匹配行时为非NULL的其他表达式,在找不到匹配行时为NULL

SELECT set_list.features, COUNT(cars.features) FROM
  (SELECT TRIM("'" FROM SUBSTRING_INDEX(SUBSTRING_INDEX(
  (SELECT TRIM(')' FROM SUBSTR(column_type, 5)) FROM information_schema.columns 
  WHERE table_name = 'cars' AND column_name = 'features'),
  ',', @r:=@r+1), ',', -1)) AS features
  FROM (SELECT @r:=0) deriv1,
  (SELECT ID FROM information_schema.COLLATIONS) deriv2
  HAVING @r <= 
  (SELECT LENGTH(column_type) - LENGTH(REPLACE(column_type, ',', ''))
  FROM information_schema.columns
  WHERE table_name = 'cars' AND column_name = 'features')) set_list
LEFT OUTER JOIN cars
ON FIND_IN_SET(set_list.features, cars.features) > 0
GROUP BY set_list.features
改编自:

我的查询以上面文章中的SQL为基础,以获得可用列值的列表。所有缩进SQL都是一个查询,如果单独执行它,就会得到列表,我从中创建一个结果集,我称之为set_list。我只是照着原样复制了这个查询,但它基本上是在做大量的字符串操作来获取列表——正如Mike Brant所建议的,如果将列表放入另一个表中,并将其合并,代码会简单得多,但可能没有那么动态


然后,我将set_列表重新连接到cars表中,将set_列表中的每个项目连接到cars中包含该功能的行中-FIND_in_set。它是一个外部联接,因此如果集合列表中的任何内容没有表示,它将以零计数出现。

如果需要这些类型的结果,为什么不将特征数据规范化到另一个表中?此问题的状态如何?如果一个答案解决了它,它应该被标记为已解决。为了能够理解它,要求你描述你的查询做了什么会不会太多?这比我的MySQL基础知识要先进得多。再次感谢@user3783407我已经添加了一个描述,如果有任何不清楚的地方,请告诉我。值得注意的是,这里的smarts是一个动态获取集合列表的查询,我从我引用的帖子中复制了它——这是一个复杂的字符串操作,可以将值列表作为结果集。在这之后,它并不比连接一些表更复杂,如果需要的话,如果您将功能列表放在另一个表中,您可以避免复杂的查询-如果您更改了集合列表,您只需要维护额外的表。