Retrieve a key-value data structure from MariaDB query - mysql

I would like to do a query to retrieve a key-value data structure without putting the burden on the code.
For example, if I have the following query:
SELECT id, nome FROM articolo
is there a way in mariaDB to throw this data into a key-value data structure so you don't do it from code and do it directly from query? Something like:
SELECT {id: nome} FROM articolo
Thanks in advance

You can use the JSON functions.
This creates an object for each row:
SELECT JSON_OBJECT(id, nome) FROM articolo;
If you want all the values in a single object, use:
SELECT JSON_OBJECTAGG(id, nome) FROM articolo

Related

Is is possible to use between and like with JSON in mysql / mariadb?

I have a table name data with a column name body containing records present in json format i.e.,
'{"createdOn": "2018-10-05T00:00:00.000+0000","id":1,"name":"abc"}',
'{"createdOn": "2018-10-06T00:00:00.000+0000","id":2,"name":"xyz"}',
'{"createdOn": "2018-10-10T00:00:00.000+0000","id":3,"name":"aaa"}',
'{"createdOn": "2018-10-25T00:00:00.000+0000","id":4,"name":"qqq"}',
I am looking to fetch and delete the records between "createdOn":"2018-10-05T00:00:00.000+0000" and "createdOn":"2018-10-10T00:00:00.000+0000" for which I am trying to write a query SELECT * FROM data where body like between '%"createdOn": "2018-10-05%' and '%"createdOn": "2018-10-10%'; but it is giving the error . How can something like this be achieved ? If anybody can help ?
Thanks
Yes, you can extract values from json and use them in queries:
select * from data where JSON_VALUE(body, '$.createdOn') between '2018-10-05T00:00:00.000+0000' and '2018-10-10T00:00:00.000+0000';
select * from data where JSON_VALUE(body, '$.name') LIKE '%a%';

How can we split the strings in mysql IN query?

I'm trying to fetch the data in NodeJs using mysql IN query.
I'm getting the data dynamically and need to get data based on textValues;
For example , let textValues = 'a1b, a2b, a3b, a4b' and my query is-
select * from table where values IN (textValues).
but this will not generate the expected output.
As I'll achieve this using
select * from table where values IN ('a1b','a2b','a3b','a4b').
i.e. textValues should be in 'a1b','a2b' which we can't store in any data types like this.
How can we achieve this with MYSQL IN query.
Thank You

SQL get value from key in dictionary

I have a column in my database which is called user_log. It basically logs everything a user does on the page. I use MySQL.
It looks like that:
user_id
user_log
1028
{ "last_login":"2022-04-08 12:03:05", "blog_entry_at":"2022-04-08 12:43:12" }
Now, I want to extract all "last_login" and get the value of it.
It is a text field, but not a dict or something else
You can use json_extract in MySQL.
SELECT user_id, json_extract(user_log, '$.last_login') as last_login FROM users;
Sample query: https://onecompiler.com/mysql/3y8a3brhr
More on json_extract here in the mariadb docs: https://mariadb.com/kb/en/json_extract/
You can simply use JSON_VALUE() function provided that the DB is of version 8.0.21+ such as
SELECT JSON_VALUE(user_log, '$.last_login') AS extracted_value
FROM t

Retrieving documents on keys using nested query

Started learning NIQL on couchbase. I am trying to retrieve multiple documents based on the keys using following nested query. Can't get it working. Is that even possible ?
SELECT * FROM Cart USE KEYS (
SELECT META().id FROM Cart WHERE META().id LIKE "100%"
)
USE KEYS expecting array of strings. Subquery generates array of Object of strings.
Use RAW in subquery to remove object when you projecting single field.
You have one of the following options
SELECT META().id, * FROM Cart WHERE META().id LIKE "100%";
OR
SELECT * FROM Cart USE KEYS (SELECT RAW META().id FROM Cart WHERE META().id LIKE "100%");
You can checkout N1QL tutorial https://query-tutorial.couchbase.com/tutorial/#1

Unserialize through query at database level itself

I have a column value stored in the database as:
a:2:{i:0;s:2:"US";i:1;s:2:"19";}
I want to unserialize it during the mysql query rather than using the php unserialize function after fetching the data.
I want to do it this way so I can join another table with the serialized value. This would avoid executing a separate query after unserializing it with php, just for the joined data.
MySQL doesn't know what a PHP serialization is. You can't do it.
You can use SUBSTRING_INDEX
For example, if you have a record like this:
a:5:{s:9:"invoiceid";s:1:"8";s:8:"balance";i:5;s:14:"broughtforward";i:3;s:6:"userid";s:5:"13908";s:10:"customerid";s:1:"3";}
You can use the below SELECT statement:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',1),':',-1) AS fieldname1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',2),':',-1) AS fieldvalue1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',3),':',-1) AS fieldname2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',4),':',-1) AS fieldvalue2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',5),':',-1) AS fieldname3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',6),':',-1) AS fieldvalue3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',7),':',-1) AS fieldname4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',8),':',-1) AS fieldvalue4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',9),':',-1) AS fieldname5,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',10),':',-1) AS fieldvalue5
FROM table;
Check this for reference: How to unserialize data using mysql without using php
How about this? This is a MySQL user-defined function with embedded php:
CREATE FUNCTION unserialize_php RETURNS STRING SONAME 'unserialize_php.so';
Usage example:
SELECT unserialize_php('O:8:"stdClass":2:{s:1:"a";s:4:"aaaa";s:1:"b";s:4:"bbbb";}', "$obj->a")
AS 'unserialized';
+--------------+
| unserialized |
+--------------+
| aaaa |
+--------------+
1 row in set (0.00 sec)
drop function unserialize_php;
Source: https://github.com/junamai2000/mysql_unserialize_php
You can create a MySQL user-defined function and call zend_eval_string inside of the function so that you can bring back PHP variables to a MySQL result. I implemented a sample program. You can try it.
From http://www.blastar.biz/2013/11/28/how-to-use-mysql-to-search-in-php-serialized-fields/
Standard array
SELECT * FROM table WHERE your_field_here REGEXP '.*;s:[0-9]+:"your_value_here".*'
Associative array
SELECT * FROM table WHERE your_field_here REGEXP '.*"array_key_here";s [0-9]+:"your_value_here".*'
It's a very bad practice to add programming language dependent structures to database. If you do so, you always have to rely on that language.
The best approach is to have normalized table structure (different fields or tables).
The next approach is to save data as a delimited string (e.g.: 0,US,1,19). Then you can use MySQL's SUBSTRING() or to use standard serialization mechanisms like JSON encode.
As mentioned by kchteam, MySQLToolBox library comes handy for this purpose using a custom defined MySQL function getPhpSerializedArrayValueByKey available here https://github.com/KredytyChwilowki/MySQLToolBox/blob/master/getPhpSerializedArrayValueByKey.sql.
After adding this function, you can retrieve any value in the serialized array by using the following syntax,
SELECT getPhpSerializedArrayValueByKey(column_name, 'array_key') AS deseializedArrayValue FROM table_name
The given array can be unserialized like,
SELECT getPhpSerializedArrayValueByKey('a:2:{i:0;s:2:"US";i:1;s:2:"19";}
', 'key_to_retrieve') AS key_to_retrieve
For serialized arrays You can use function getPhpSerializedArrayValueByKey from here
You can join your table simply in this way
SELECT
table_to_join.ID as table_to_join_ID ,
serialized_table.ID AS serialized_table_ID,
FROM
table_to_join
LEFT JOIN
serialized_table ON serialized_table.array_field REGEXP CONCAT_WS('','.s:[0-9];s:', table_to_join.ID ,';.') ;
Take mention. I use index from 0 to 9 in table. If you have other indexes you must correct regexp