SQL逗号分隔的字段统计(摘自网络)

前言:

由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式。即同一个列中存储了多个属性值(具体结构见下表)。

这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果。

表数据:

ID  Value

1 tiny,small,big

2 small,medium

3 tiny,big

期望得到结果:

ID Value

1 tiny

1 small

1 big

2 small

2 medium

3 tiny

3 big

正文:

www.2cto.com

#需要处理的表

create table tbl_name (ID int ,mSize varchar(100));

insert into tbl_name values (1,‘tiny,small,big‘);

insert into tbl_name values (2,‘small,medium‘);

insert into tbl_name values (3,‘tiny,big‘);

#用于循环的自增表

create table incre_table (AutoIncreID int);

insert into incre_table values (1);

insert into incre_table values (2);

insert into incre_table values (3);

select a.ID,substring_index(substring_index(a.mSize,‘,‘,b.AutoIncreID),‘,‘,-1)

from

tbl_name a

join

incre_table b

on b.AutoIncreID <= (length(a.mSize) - length(replace(a.mSize,‘,‘,‘‘))+1)

order by a.ID;

原理分析:

这个join最基本原理是笛卡尔积。通过这个方式来实现循环。

以下是具体问题分析:

length(a.Size) - length(replace(a.mSize,‘,‘,‘‘))+1  表示了,按照逗号分割后,改列拥有的数值数量,下面简称n

join过程的伪代码:

根据ID进行循环

{

判断:i 是否 <= n

{

获取最靠近第 i 个逗号之前的数据, 即 substring_index(substring_index(a.mSize,‘,‘,b.ID),‘,‘,-1)

i = i +1

}

ID = ID +1

}  www.2cto.com

总结:

这种方法的缺点在于,我们需要一个拥有连续数列的独立表(这里是incre_table)。并且连续数列的最大值一定要大于符合分割的值的个数。

例如有一行的mSize 有100个逗号分割的值,那么我们的incre_table 就需要有至少100个连续行。

当然,mysql内部也有现成的连续数列表可用。如mysql.help_topic: help_topic_id 共有504个数值,一般能满足于大部分需求了。

改写后如下:

select a.ID,substring_index(substring_index(a.mSize,‘,‘,b.help_topic_id+1),‘,‘,-1)

from

tbl_name a

join

mysql.help_topic b

on b.help_topic_id < (length(a.mSize) - length(replace(a.mSize,‘,‘,‘‘))+1)

order by a.ID;

=========================================================================

问题:

有个表中的一个字段Author,如下ID        Author1         张三2         张三,李四3         王五4         李四5         张三,李四,王五

现在想查询出这样的结果Author        Count张三            3李四            3王五            2

sql server 解答:
if object_id(‘Tempdb..#Num‘) is not null      drop table #Num  select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b  Select       Author=substring(a.Author,b.ID,charindex(‘,‘,a.Author+‘,‘,b.ID)-b.ID),count(*) from       table1 a,#Num b  where      charindex(‘,‘,‘,‘+a.Author,b.ID)=b.IDgroup by substring(a.Author,b.ID,charindex(‘,‘,a.Author+‘,‘,b.ID)-b.ID);

table1替换成你自己表名,top 100 那个100你就替换个稍微大点的数吧
时间: 2024-10-06 06:02:13

SQL逗号分隔的字段统计(摘自网络)的相关文章

SQL 阻塞(摘自网络)

/* 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源, 造成这些会话发出的请求进入等待的状态.SQL Server 默认会让被阻塞的请求无限期地一直等待, 直到原来的事务释放相关的锁,或直到它超时 (根据 SET LOCK_TIMEOUT ).服务器关闭. 进程被杀死.一般的系统中,偶尔有短时间的阻塞是正常且合理的:但若设计不良的程序,就可能导致长时间的阻塞, 这样就不必要地锁定了资源,而且阻塞了其他会话欲读取或更新的需求.遇到这种情况,可能就需要手工排除

C# Linq to sql 实现 group by 统计多字段 返回多字段

Linq to sql 使用group by 统计多个字段,然后返回多个字段的值,话不多说,直接上例子: var wflist = from u in db.TWelFare where u.fy_no == fy_no orderby u.we_no group u by new { weno = u.we_no, wename = u.we_name } into g select new { g.Key.weno, g.Key.wename }; 结果就是根据we_no和we_name的统

字符串相似度计算的方法,使用SQL以及C#实现,本文非原创摘自网络(.NET SQL技术交流群入群206656202需注明博客园)

1 CREATE function get_semblance_By_2words 2 ( 3 @word1 varchar(50), 4 @word2 varchar(50) 5 ) 6 returns nvarchar(4000) 7 as 8 begin 9 declare @re int 10 declare @maxLenth int 11 declare @i int,@l int 12 declare @tb1 table(child varchar(50)) 13 declare

SQL Server-深入剖析统计信息

转自: http://www.cnblogs.com/zhijianliutang/p/4190669.html   概念理解 关于SQL Server中的统计信息,在联机丛书中是这样解释的 查询优化的统计信息是一些对象,这些对象包含与值在表或索引视图的一列或多列中的分布有关的统计信息.查询优化器使用这些统计信息来估计查询结果中的基数或行数.通过这些基数估计,查询优化器可以创建高质量的查询计划.例如,查询优化器可以使用基数估计选择索引查找运算符而不是耗费更多资源的索引扫描运算符,从而提高查询性能

Mysql explain分析SQL语句之字段属性说明

在 explain的帮助下,您就知道什么时候该给表添加索引,以使用索引来查找记录从而让select 运行更快.如果由于不恰当使用索引而引起一些问题的话,可以运行 analyze table来更新该表的统计信息,例如键的基数,它能帮您在优化方面做出更好的选择. explain 返回了一行记录,它包括了 select语句中用到的各个表的信息.这些表在结果中按照mysql即将执行的查询中读取的顺序列出来.mysql用一次扫描多次连接(single- sweep,multi-join)的方法来解决连接.

vertica时间计算SQL语句实例:统计一天内登录的用户

SQL语句实例: select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) day as integer )<=1; 或 select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) hour as integer )<=24; 大家可以根据表结构稍作调整后使用 vertica时间

tomcat解压版安装(摘自网络)

配置Tomcat[解压版] 选择解压版的Tomcat的理由是可以让我们使用多个Tomcat,但是配置上就会出现一些问题,需要我们手动进行更改配置.我的Tomcat版本是:apache-tomcat-6.0.16.zip 给个链接:http://tomcat.apache.org 下载完成后,解压到C:\Tomcat6(设置你的路径),检查环境变量JAVA_HOME是否存在:一般JDK安装时会自动设置,如果没有就创建,JAVA_HOME的值设为JDK的安装根路径. 环境变量位置:我的电脑 -> 右

Android:控件WebView显示网页 -摘自网络

WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要处理解析,渲染网页等浏览器做的事情 setWebChromeClient:辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 WebViewClient就是帮助WebView处理各种通知.请求事件的. 在AndroidManifest.xml设置访问网络权限:

Mysql查询用逗号分隔的字段-字符串函数FIND_IN_SET(),以及此函数与in()函数的区别

查询用逗号分隔的字段,可以用字符串函数FIND_IN_SET(): 查询数据库表中某个字段(值分行显示),可以用函数in(). 今天工作中遇到一个问题,就是用FIND_IN_SET()函数解决的. 第一部分: FIND_IN_SET()函数用法, 查询用逗号分隔的字段, 表A中 go_value字段的值是以逗号分割, 查询 go_value字段中含有3的行: select * from A where find_in_set('3', go_value); 第二部分: in()函数用法 查询数据