从 blob 列中提取子字符串以添加以在子字段中使用它

Extract substring from a blob column to make an addition to use it in subfield

我想提取初始为 blob 字段的列的值。

所以我有这个 SQL 查询:

CREATE TEMPORARY TABLE IF NOT EXISTS single_commande AS (
    SELECT o.order_id, coi.order_item_id, CONVERT(coic.adjustments_value USING utf8) AS ajustement
    FROM all_orders o
        LEFT JOIN commerce_order_item coi
            on o.order_id = coi.order_id
        LEFT JOIN commerce_order_item__adjustments coic
            on coic.entity_id = coi.order_item_id
    WHERE o.order_id = 51
);

哪个给了我那些数据:

调整值如下所示:

O:32:"Drupal\commerce_order\Adjustment":7:{s:7:"..type";s:3:"tax";s:8:"..label";s:4:"Taxe";s:9:"..amount";O:27:"Drupal\commerce_price\Price":2:{s:9:"..number";s:4:"4.60";s:15:"..currencyCode";s:3:"EUR";}s:13:"..percentage";s:3:"0.2";s:11:"..sourceId";s:48:"tva|default|56fdce53-c1db-4ae2-8612-c3f0a4e6e4da";s:11:"..included";b:1;s:9:".*.locked";b:0;}

而且我需要从这个字符串中提取 number 值(这里是 4.6),在每一行上提取这个值并求和所有这些数字得到总数。

我需要这个总数用于另一个查询,这个:

CREATE TEMPORARY TABLE IF NOT EXISTS traiteur_commandes AS (
    SELECT o.order_id     AS `CommandeID`,
           (SUM OF ALL ADJUSTMENT BY order_id  AS `TotalHT` /* to calculate */
    FROM all_orders o
        ...
    ORDER BY o.order_id
);

最后,我将删除 CREATE TEMPORARY TABLE IF NOT EXISTS single_commande 因为我需要使用子查询,这是仅供测试。

我想我必须做类似的事情

SELECT sum(CONVERT(coic.adjustments_value USING utf8 /* DO SOMETHING TO GET THE VALUE */ )) AS ajustment

也许我可以用类似 REGEXP '.*Price";s:[0-9]+:"number".*' 的正则表达式提取值(我现在正在研究正则表达式)

知道这是最好的方法还是我完全错了?

EDIT :这是来自 drupal 商务模块,所以我无法更改数据库中的字段。还有,我不能用php什么的,只能通过MySQL.

导出数据

编辑:这是 MySQL 的解决方案。根据您的评论,我相信您使用的是 MariaDB,而不是 MySQL。这两个数据库产品不兼容。

我通过将变量 @s 设置为您显示的 PHP 序列化对象来进行测试。您将在查询临时 table.

时使用 ajustement
set @s = 'O:32:"Drupal\commerce_order\Adjustment":7:{s:7:"..type";s:3:"tax";s:8:"..label";s:4:"Taxe";s:9:"..amount";O:27:"Drupal\commerce_price\Price":2:{s:9:"..number";s:4:"4.60";s:15:"..currencyCode";s:3:"EUR";}s:13:"..percentage";s:3:"0.2";s:11:"..sourceId";s:48:"tva|default|56fdce53-c1db-4ae2-8612-c3f0a4e6e4da";s:11:"..included";b:1;s:9:".*.locked";b:0;}'

首先使用 REGEXP_SUBSTR() 提取价格对象。

mysql> select regexp_substr(@s,
  '"Drupal\\commerce_price\\Price":2:\{[^}]*\}', 1, 1, 'c') as PriceObject;
+----------------------------------------------------------------------------------------------+
| PriceObject                                                                                  |
+----------------------------------------------------------------------------------------------+
| "Drupal\commerce_price\Price":2:{s:9:"..number";s:4:"4.60";s:15:"..currencyCode";s:3:"EUR";} |
+----------------------------------------------------------------------------------------------+

在此基础上,使用另一个提取“..number”字段及其后续值。

mysql> select regexp_substr(
  regexp_substr(@s,
    '"Drupal\\commerce_price\\Price":2:\{[^}]*\}', 1, 1, 'c'),
  '"..number";[^;]*;') as number;
+------------------------+
| number                 |
+------------------------+
| "..number";s:4:"4.60"; |
+------------------------+

在此基础上,使用另一个提取值。

mysql> select regexp_substr(
  regexp_substr(
    regexp_substr(@s,
      '"Drupal\\commerce_price\\Price":2:\{[^}]*\}', 1, 1, 'c'),
    '"..number";[^;]*;'),
  '"[[:digit:].]+"') as number;
+--------+
| number |
+--------+
| "4.60" |
+--------+

然后去除引号并转换为十进制数。

mysql> select cast(json_unquote(
  regexp_substr(
    regexp_substr(
      regexp_substr(@s,
        '"Drupal\\commerce_price\\Price":2:\{[^}]*\}', 1, 1, 'c'),
      '"..number";[^;]*;'),
    '"[[:digit:].]+"')) as decimal(9,2)) as number;
+--------+
| number |
+--------+
|   4.60 |
+--------+

这看起来像一个 PHP“序列化”对象。如果是这样,读取 blob int,比如 $x unserialize($x),然后使用 var_dump 或 print_r 看看它看起来像 PHP。然后只需进入 $x 即可获取您需要的任何字段。

__PHP_Incomplete_Class Object
(
    [__PHP_Incomplete_Class_Name] => Drupal\commerce_order\Adjustment
    [..?type] => tax
    [..?label] => Taxe
    [..?amount] => __PHP_Incomplete_Class Object
        (
            [__PHP_Incomplete_Class_Name] => Drupal\commerce_price\Price
            [..?number] => 4.60
            [..?currencyCode] => EUR
        )

    [..?percentage] => 0.2
    [..?sourceId] => tva|default|56fdce53-c1db-4ae2-8612-c3f0a4e6e4da
    [..?included] => 1
    [.*.locked] => 
)

(我添加了“?”以使字符串足够长;我不知道该问题的原因。)