SQL MariaDB应用正则表达式到列

huangapple go评论61阅读模式
英文:

SQL MariaDB apply regex to column

问题

我将一些操作从后端服务移到数据库中。我正在创建一个视图,将几个表转换成一个单一的表。例如,用户表每个用户有一行,用户元数据表每个用户的每个元数据字段有一行,所以每个用户可以有多个元数据字段,这就是为什么我想通过一个视图将它们合并成一个单一的表。

顺便说一下,DBUser 已被删除。

create definer = DBUser@`%` view mm_users as
select `DBUser`.`wp_users`.`ID`                                                                             AS `id`,
       `DBUser`.`wp_users`.`user_login`                                                                     AS `login`,
       `DBUser`.`wp_users`.`user_email`                                                                     AS `email`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'nickname',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `nickname`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'first_name',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `first_name`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'last_name',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `last_name`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'user-jahrgangsstufe',
              `DBUser`.`wp_usermeta`.`meta_value`, NULL))                                                   AS `class`,
       max(case
               when `DBUser`.`wp_usermeta`.`meta_key` = 'user-schule'
                   then `DBUser`.`wp_usermeta`.`meta_value` end)                                            AS `school`,
       case
           when `DBUser`.`wp_usermeta`.`meta_key` = 'je_data_store_angebote-favoriten'
               then regexp_replace(`DBUser`.`wp_usermeta`.`meta_value`, 's:4:"([0-9]{1,4})"', '\\1') end   AS `favorites`,
       max(case
               when `DBUser`.`wp_usermeta`.`meta_key` = 'wp_capabilities' then regexp_replace(
                       `DBUser`.`wp_usermeta`.`meta_value`,
                       '^a:1:{s:[0-9]+:"(subscriber|editor|contributor|administrator)";b:1;}$', '\\1') end) AS `role`
from (`DBUser`.`wp_users` left join `DBUser`.`wp_usermeta`
      on (`DBUser`.`wp_users`.`ID` = `DBUser`.`wp_usermeta`.`user_id`))
where `DBUser`.`wp_usermeta`.`meta_key` in
      ('nickname', 'first_name', 'last_name', 'wp_capabilities', 'user-jahrgangsstufe', 'user-schule',
       'je_data_store_angebote-favoriten')
group by `DBUser`.`wp_users`.`ID`;

除了转换 je_data_store_angebote-favoriten 元数据外,其他都能正常工作。为了澄清,这个元数据的值是一个序列化的 PHP 字符串,包含 0 到 5 个值,以下是几个示例:

a:0:{}
a:1:{i:0;s:4:"3131";}
a:2:{i:0;s:4:"2535";i:1;s:4:"2539";}
a:3:{i:0;s:4:"3119";i:1;s:4:"3086";i:2;s:4:"2615";}
a:4:{i:0;s:4:"2950";i:1;s:4:"3185";i:2;s:4:"2478";i:3;s:4:"2568";}
a:5:{i:0;s:4:"3025";i:1;s:4:"3032";i:2;s:4:"3202";i:3;s:4:"2550";i:4;s:4:"3080";}
a:5:{i:0;s:4:"25";i:1;s:4:"7";i:2;s:4:"33556";i:3;s:4:"4597";i:4;s:4:"21594";}

我已经将 s:4:"([0-9]{1,4})" 输入到 https://regex101.com/,它匹配我需要的一切,但是在创建这个视图时,所有用户的 favorites 列都是 null。为什么会这样?我可以应用正则表达式模式来获取用户的角色,为什么不能用同样的方法获取用户的收藏?

英文:

I'm moving a couple operations from my backend services to the database. I'm currently creating a view to transform a couple tables into a single table. As an example, the user table has one row per user, and the user meta table has one row per meta field per user, so each user can have multiple meta fields, hence why I'd like to combine this into a single table through a view.

Sidenote, DBUser has been redacted.

create definer = DBUser@`%` view mm_users as
select `DBUser`.`wp_users`.`ID`                                                                             AS `id`,
       `DBUser`.`wp_users`.`user_login`                                                                     AS `login`,
       `DBUser`.`wp_users`.`user_email`                                                                     AS `email`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'nickname',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `nickname`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'first_name',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `first_name`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'last_name',
              `DBUser`.`wp_usermeta`.`meta_value`,
              NULL))                                                                                        AS `last_name`,
       max(if(`DBUser`.`wp_usermeta`.`meta_key` = 'user-jahrgangsstufe',
              `DBUser`.`wp_usermeta`.`meta_value`, NULL))                                                   AS `class`,
       max(case
               when `DBUser`.`wp_usermeta`.`meta_key` = 'user-schule'
                   then `DBUser`.`wp_usermeta`.`meta_value` end)                                            AS `school`,
       case
           when `DBUser`.`wp_usermeta`.`meta_key` = 'je_data_store_angebote-favoriten'
               then regexp_replace(`DBUser`.`wp_usermeta`.`meta_value`, 's:4:"([0-9]{1,4})"',
                                   '\\1') end                                                               AS `favorites`,
       max(case
               when `DBUser`.`wp_usermeta`.`meta_key` = 'wp_capabilities' then regexp_replace(
                       `DBUser`.`wp_usermeta`.`meta_value`,
                       '^a:1:{s:[0-9]+:"(subscriber|editor|contributor|administrator)";b:1;}$', '\\1') end) AS `role`
from (`DBUser`.`wp_users` left join `DBUser`.`wp_usermeta`
      on (`DBUser`.`wp_users`.`ID` = `DBUser`.`wp_usermeta`.`user_id`))
where `DBUser`.`wp_usermeta`.`meta_key` in
      ('nickname', 'first_name', 'last_name', 'wp_capabilities', 'user-jahrgangsstufe', 'user-schule',
       'je_data_store_angebote-favoriten')
group by `DBUser`.`wp_users`.`ID`;

Everything works apart from transforming the je_data_store_angebote-favoriten metadata. For clarification, this meta value is a serialized PHP string with 0 to 5 values, a couple examples:

a:0:{}
a:1:{i:0;s:4:"3131";}
a:2:{i:0;s:4:"2535";i:1;s:4:"2539";}
a:3:{i:0;s:4:"3119";i:1;s:4:"3086";i:2;s:4:"2615";}
a:4:{i:0;s:4:"2950";i:1;s:4:"3185";i:2;s:4:"2478";i:3;s:4:"2568";}
a:5:{i:0;s:4:"3025";i:1;s:4:"3032";i:2;s:4:"3202";i:3;s:4:"2550";i:4;s:4:"3080";}
a:5:{i:0;s:4:"25";i:1;s:4:"7";i:2;s:4:"33556";i:3;s:4:"4597";i:4;s:4:"21594";}

I've put s:4:&quot;([0-9]{1,4})&quot; into <https://regex101.com/> and it matches everything I need it to, but when creating this view, the favourites column is null for all users. What gives? I can apply a regex pattern to get the role of the user, why can't I do the same to get the favourites of a user?

答案1

得分: 1

那是一个棘手的问题,但正如我想的那样,你可以使用GROUP_CONCAT来摆脱空值,你可以像你已经做过的那样操作。

CREATE TABLE tex
(`val` varchar(81))
;
INSERT INTO tex
(`val`)
VALUES
('a:0:{}'),
('a:1:{i:0;s:4:"3131";}''),
('a:2:{i:0;s:4:"2535";i:1;s:4:"2539";}''),
('a:3:{i:0;s:4:"3119";i:1;s:4:"3086";i:2;s:4:"2615";}''),
('a:4:{i:0;s:4:"2950";i:1;s:4:"3185";i:2;s:4:"2478";i:3;s:4:"2568";}''),
('a:5:{i:0;s:4:"3025";i:1;s:4:"3032";i:2;s:4:"3202";i:3;s:4:"2550";i:4;s:4:"3080";}''),
('a:5:{i:0;s:4:"25";i:1;s:4:"7";i:2;s:4:"33556";i:3;s:4:"4597";i:4;s:4:"21594";}'')
;

> 状态 &gt; 记录数: 7 重复数: 0 警告数: 0 &gt;

SELECT
GROUP_CONCAT(SUBSTR(REGEXP_REPLACE(val, '^a:\\d+:\\{\\}|a:\\d+:\\{i:\\d+;s:\\d+:&quot;|&quot;;i:\\d+;s:\\d+:&quot;|&quot;;\\}$', ','),2) SEPARATOR  '') AS string_values
FROM
tex;
string_values
3131,2535,2539,3119,3086,2615,2950,3185,2478,2568,3025,3032,3202,2550,3080,25,7,33556,4597,21594,

fiddle

英文:

That was a tricky one, but as i thought you can use GROUP_CONCAT

to get rid of the empty one, you can do as you already have done

CREATE TABLE tex
(`val` varchar(81))
;
INSERT INTO tex
(`val`)
VALUES
(&#39;a:0:{}&#39;),
(&#39;a:1:{i:0;s:4:&quot;3131&quot;;}&#39;),
(&#39;a:2:{i:0;s:4:&quot;2535&quot;;i:1;s:4:&quot;2539&quot;;}&#39;),
(&#39;a:3:{i:0;s:4:&quot;3119&quot;;i:1;s:4:&quot;3086&quot;;i:2;s:4:&quot;2615&quot;;}&#39;),
(&#39;a:4:{i:0;s:4:&quot;2950&quot;;i:1;s:4:&quot;3185&quot;;i:2;s:4:&quot;2478&quot;;i:3;s:4:&quot;2568&quot;;}&#39;),
(&#39;a:5:{i:0;s:4:&quot;3025&quot;;i:1;s:4:&quot;3032&quot;;i:2;s:4:&quot;3202&quot;;i:3;s:4:&quot;2550&quot;;i:4;s:4:&quot;3080&quot;;}&#39;),
(&#39;a:5:{i:0;s:4:&quot;25&quot;;i:1;s:4:&quot;7&quot;;i:2;s:4:&quot;33556&quot;;i:3;s:4:&quot;4597&quot;;i:4;s:4:&quot;21594&quot;;}&#39;)
;

> status
&gt; Records: 7 Duplicates: 0 Warnings: 0
&gt;

SELECT
GROUP_CONCAT(SUBSTR(REGEXP_REPLACE(val, &#39;^a:\\d+:\\{\\\}|a:\\d+:\\{i:\\d+;s:\\d+:&quot;|&quot;;i:\\d+;s:\\d+:&quot;|&quot;;\\}$&#39;, &#39;,&#39;),2) SEPARATOR  &quot;&quot;) AS string_values
FROM
tex;
string_values
3131,2535,2539,3119,3086,2615,2950,3185,2478,2568,3025,3032,3202,2550,3080,25,7,33556,4597,21594,

fiddle

huangapple
  • 本文由 发表于 2023年3月7日 03:16:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654937.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定