利用SQL将查询到的string值分离,以及python实现导出csv文件方法

3 篇文章 0 订阅

1、问题描述

最近一小伙伴需要做一个SQL查询操作:

  • 获取到两列A、B,B是一个string,string以,分隔,需要将B拆封,显示 A,B1;A,B2…
    • 类似于下面的操作:
      在这里插入图片描述

ps:根据自己对SQL的认识,不使用SQL 函数的情况下很难做到,如果是将查询结果导出,再利用python脚本这种分离非常容易实现。


2、解决方案

查了一些相关资料,上图的这种操作,MySQL中几个拆分字符串的函数,分别为:

  • SUBSTRING_INDEX(str,delim,count)
    • 例如:SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2); 输出: ‘www.mysql’
  • SUBSTRING(str,pos), SUBSTRING(str FROM pos), SUBSTRING(str,pos,len), SUBSTRING(str FROM pos FOR len)
    • SUBSTRSUBSTRING的简写,都可使用
    • 例如:SELECT SUBSTRING('Quadratically',5,6);,输出: ‘ratica’

但以上两个函数能拆分,但都不能满足当前需要求,同时MySQL中并没有 split函数,上面的查询操作属于一些比较高级的操作,所以需要使用:存储过程或函数解决,函数的写法可参见 2-1.

2-1、定义split函数

MySQL中并没有 split函数,在数据库中定义SPLIT_STR 函数即可,如下所示。

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

这里只是一个说明,函数就是利器在手,什么操作都能实现,可根据需求实现函数,又是一个值得深挖的操作,在此不再深入介绍。

2-2、借助python实现

这里更方便的是,两步操作

  • 将查询结果导出(csv文件)
  • 使用python脚本进行解析

Python脚本为:

#!/usr/bin/env python
# coding: utf-8

import csv
file_path = "./data.csv"
save_file_path = "./convert_data.csv"

output = open(save_file_path, "w", newline='')
writer = csv.DictWriter(output, ['iterm','iterm_val'])
writer.writeheader()

with open(file_path, newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        iterm = row['iterm']
        valules = row["iterm_values"]
        for val in valules.split(','):
            writer.writerow({'iterm':iterm, 'iterm_val': val})
            # print({'iterm':iterm, 'iterm_val': val})

# 关闭已经打开的文件
output.close()
csvfile.close()

2-3、利用MySQL自带函数

在整理该问题的反向操作时,换个角度搜索了下,没想到果真找到了该问题的答案,不用创建新表,在哪都可操作,脚本如下,可以根据自己的表实际情况进行操作,已经测试,以下脚本可以实现效果。

select
  key_value.iterm,
  SUBSTRING_INDEX(SUBSTRING_INDEX(key_value.iterm_values, ',', numbers.n), ',', -1) iterm_values
from
  (select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5) numbers INNER JOIN key_value
  on CHAR_LENGTH(key_value.iterm_values)
     -CHAR_LENGTH(REPLACE(key_value.iterm_values, ',', ''))>=numbers.n-1
order by
  iterm, n;

3、反向操作(多行内容合并)

如果将以上进行反向操作,如下图所示:
在这里插入图片描述
该问题,在MySQL中可以使用 GROUP_CONCAT函数,使用方法如下:

SELECT person_id,
   GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

该问题可参考:


相关资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值