【问题标题】:count of distincts substring in query查询中不同子字符串的计数
【发布时间】:2014-08-23 20:19:05
【问题描述】:

我正在尝试创建一个查询来计算(或至少检索)列中子字符串的不同出现次数。

我有一栏是这样的:

elem1=value1|elem2=value2|elem3=value3

我想检索 elem2 的不同值和出现次数。

SELECT
    substring(
        column , LOCATE( 'elem2=' , column ) + $1 , $2 
    ) AS a ,
    COUNT(*) b ,
FROM
   column ORDER BY a;

谢谢

【问题讨论】:

  • 在一个字段中存储多个值几乎是数据库设计不良的标志。特别是如果您必须与单身人士一起工作。更糟糕的是,如果这些值甚至不是字符分隔的......
  • 啊啊啊啊!!!托尼尖叫着跑开了。

标签: mysql sql


【解决方案1】:

这是实现指定结果的一种方法。

SELECT COUNT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1)) 从T WHERE t.col LIKE '%elem2=%'

显然,我误读了这个问题(上面的查询返回了不同值的计数。或者,我只是在处理繁琐的字符串解析时忘记了指定的结果。

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1) AS a
     , COUNT(*) AS b
  FROM t
 WHERE t.col LIKE '%elem2=%'
 GROUP BY SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1)
 ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1)

注意:

请注意,SQL 并不是真正为从字符串中解析值而设计的。

此类数据的规范关系模式将创建一个表,其中包含名为elem1elem2elem3 的列,并将每个单独的值存储在一个列中。

例如:

CREATE TABLE t 
( id     INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, elem1  VARCHAR(80)
, elem2  VARCHAR(80)
, elem3  VARCHAR(80)
);
INSERT INTO t (elem1, elem2, elem3) VALUES ('value1', 'value2', 'value3');

要获取 elem2 列中不同值的计数,我们会执行以下操作。

SELECT COUNT(DISTINCT elem2)
  FROM t

获取 elem2 的不同值以及出现次数

SELECT elem2    AS a
     , COUNT(*) AS b
  FROM t
 GROUP BY elem2
 ORDER BY elem2

这与我回答开头的查询基本相同;第一个查询只需要解析字符串中的'elem2=value2'

【讨论】:

  • @Tony Hopkinson:我最初有“做解析的繁重工作”,但它不仅仅是解析。小套装不会注意到丑陋的表现;只有在更大的集合中才会变得明显。我们预计后续问题是:“为什么我的查询这么慢?”
  • @spencer7593:我最近得到了那个数据库,它很有效率,所以它不能重新设计(至少现在),但我可以看到这个设计的问题。感谢您的回答,但是(据我了解)它正在计算所有具有 "elem2=" 的行,但所有行都具有该子字符串。我需要的是显示 elem2 的不同值,并显示每个值的出现。再次感谢您的帮助。
  • @chomsky:我已经更新了答案;原始查询回答了一个不同的问题(不同值的计数);我已将其替换为返回不同值列表和出现次数的查询。我不是说你必须重新设计数据库;我曾经遇到过这样的情况,我提供了一个文件,并且更容易将它按原样加载到数据库中,并使用 SQL 来处理它。这就是为什么这个问题值得回答。我的意思是建议规范的关系设计将有助于避免繁琐的语法。
  • @chomsky:我为你和其他处于这种位置的人感到抱歉。我很欣赏 spencer7593 的解决方案,但我不会鼓励任何人开始这样的设计。但他们确实......像你这样的人必须为此付出代价。
猜你喜欢
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2019-07-08
  • 2021-03-16
  • 1970-01-01
  • 2012-10-24
相关资源
最近更新 更多