从 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] =>
)
(我添加了“?”以使字符串足够长;我不知道该问题的原因。)
我想提取初始为 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] =>
)
(我添加了“?”以使字符串足够长;我不知道该问题的原因。)