如何使用MySQL存储过程对管道分隔的字段进行计数和排序?

时间:2017-05-01 22:46:18

标签: mysql stored-procedures

我需要创建一个存储过程,它将返回管道分隔字段中遇到的每个唯一值的总计数,大致采用图2中的格式。幸运的是,这些值只会是“value1”,“value2” “或”value3“,如果这使事情变得更简单。我最初计划输出数据并通过爆炸数据和循环遍历字符串匹配来在PHP中对其进行排序,但是有特殊情况需要我使用存储过程并且之前我没有使用过存储过程。

我正在解释的数据采用下面显示的格式,其中'valuelist'字段是包含许多值的竖线分隔字段。我需要找出每个值在给定日期发生的次数。

(下图1)数据库中的数据是什么样的。

id, date, valuelist
1, 2017-01-01, value1|value2|value3
2, 2017-01-01, value1|value2
3, 2017-01-01, value1

因此select date, valuelist from db.table where id = 1;的查询将返回2017-01-01, value1|value2|value3

(下图2)所需的计数输出表示每个值在特定日期发生的次数。例如,使用图1中的数据,如果我们询问2017-01-01,输出应该是这样的。

value1: 3
value2: 2
value3: 1

2 个答案:

答案 0 :(得分:0)

假设您要将3|2|1转换为321的单独行; MySQL(或几乎任何基于SQL的RDBMS)都不适合这种输出。

无需进入实际的程序代码,您可以在以下程序中执行以下操作:

  1. 将值存储在本地变量中
  2. 使用更通用的存储函数(应该很容易在这里找到一个)到" split"分隔符|上的字符串;或者"循环"通过你的字符串使用"得到第n个"函数迭代地拆分它。
  3. 将值存储到临时表
  4. 在临时表上使用SELECT作为程序的结果集。

答案 1 :(得分:0)

看看这个:

详细说明给定的样本数据:

SELECT  date,fval as allValue,count(fval) as ValueCount from
(select date,fval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a

union all

select date,sval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a

UNION all


select date,tval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a) as a
where fval !='' GROUP BY fval,date

最终查询:

SELECT  date,fval as allValue,count(fval) as ValueCount from
(select date,fval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable) as a)as a) as a

union all

select date,sval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable as a)as a) as a

UNION all


select date,tval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id,  date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable) as a)as a) as a) as a
where fval !='' GROUP BY fval,date

<强>结果:

2017-01-01  value1  3
2017-01-01  value2  2
2017-01-01  value3  1