I have a json object in my database table field like following :
[{"user_id":"xyz","viewed":"false","answered":"false","denied":"false"}].
the other fields are id, q_id and stuff.
I want to search for the user xyz in the table!how can i do that using mysql?
JSON Parsing in MySQL Using Common_schema
Try following query using common schema
select * from tablename where common_schema.extract_json_value(tablename.columnName,'/user_id') = 'xyz';
Reference: http://mechanics.flite.com/blog/2013/04/08/json-parsing-in-mysql-using-common-schema/
If the object pattern is same across then you can use the substring_index function to parse the data, below is the example of finding the user_id from this pattern
mysql> select replace(substring_index(substring_index('[{"user_id":"xyz","viewed":"false","answered":"false","denied":"false"}]','"user_id":',-1),',',1),'"','') as user_id;
+---------+
| user_id |
+---------+
| xyz |
+---------+
Now if you want to select all the rows having user_id = xyz you can use the above as
select * from table_name
where replace(substring_index(substring_index('[{"user_id":"xyz","viewed":"false","answered":"false","denied":"false"}]','"user_id":',-1),',',1),'"','') = 'xyz';
thank you for your answers. But i just used a like query and it worked
SELECT viewers from tablename where viewers like '%\"user_id\":\"xyz\"%' && qid= 1;
In mysql there is a functionality for dba called common schema. It has json functionality.
Or
use find_in_set() function to find coma seperated values in json.
Related
I have a table which contains a column "owners", which has json data in it like this:
[
{
"first":"bob",
"last":"boblast"
},
{
"first":"mary",
"last": "marylast"
}
]
I would like to write a query that would return for each row that contains data like this, a column that has all of the first names concatenated with a comma.
i.e.
id owners
----------------------------
1 bob,mary
2 frank,tom
Not on mysql 8.0 yet.
You can get the values as a JSON array:
SELECT JSON_EXTRACT(owners, '$[*].first') AS owners ...
But that returns in JSON array format:
+-----------------+
| owners |
+-----------------+
| ["bob", "mary"] |
+-----------------+
JSON_UNQUOTE() won't take the brackets and double-quotes out of that. You'd have to use REPLACE() as I show in a recent answer here:
MYSQL JSON search returns results in square brackets
You should think about not storing data in JSON format if it doesn't support the way you need to query them.
Here is another option, get a helper table with running numbers up to the max json array length, and extract values by individual index, after that group_concat the values, something like this:
SELECT g.id, GROUP_CONCAT(g.name)
FROM (
SELECT a.id, JSON_UNQUOTE(JSON_EXTRACT(a.owners, CONCAT('$[', n.idx, '].first'))) name
FROM running_numbers n
JOIN mytable a
) g
GROUP BY g.id
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=d7453c9edf89f79ca4ab2f63578b320c
In my column I can have either a string like : "data+" or "data+data+data+..(undefined times)..+"
I simply need to get the column where I have multiples data and not only one.
I tried with
mycol NOT LIKE '%+'
But it didn't work...
Actually I don't know the data it is a string that varies : 'blabla' or 'aString' or 'whatever'
If I had in my columns
'jdsjpgsg+jdsjpgsg+', 'dvgff+', 'ffef+eefds+ghghgh+'
I want to select only
'jdsjpgsg+jdsjpgsg+',
'ffef+eefds+ghghgh+',
NOT 'dvgff+' !
if you want to search '..xxx+..' then you should be use xxx+%
if you want to search '..+xxx..' then you should be use %+xxx
if you want to search '..++..' then you should be use %++%
if you want to search '..+..+..' then you should be use %+%+%
It is what I get too and I dont want that. It is actually what i don't want to select. If I had jdsjpgsg+jdsjpgsg+ in my table I want to select it and NOT jdsjpgsg+ It is tricky...
so you can try like '%+%+%' to exclude just one '+'
CREATE TABLE TestTable
(`text` varchar(90))
;
INSERT INTO TestTable
(`text`)
VALUES
('jdsjpgsg+jdsjpgsg+'),
('dvgff+'),
('ffef+eefds+ghghgh+')
;
select * from TestTable
where text like '%+%+%'
| text |
|--------------------|
| jdsjpgsg+jdsjpgsg+ |
| ffef+eefds+ghghgh+ |
SQL Fiddle Demo Link
The % is the wildcard character. You should be using the % after data. Try like:
SELECT * FROM `table` WHERE `mycol` NOT LIKE 'data+%'
The above query will filter out all the records that have any characters after data+.
I am using rails-4.2.1 and is trying to fetch data from two tables subjects and elective_subjects table in a single query. As rails 4 does not support UNION , I wrote a raw sql query. I want to search by name in both tables. My code is given below
query = "(SELECT id as id, name as name, reference as reference from subjects where name like '#{search}') UNION (SELECT id as id, name as name, null as reference from elective_subjects where name like '#{search}')"
#subjects = ActiveRecord::Base.connection.execute(query)
It is working but when I provide ' in my search the query breaks. So how can I make it a prepared statement. So that sql injection can be avoided
This question is super old and no cares anymore, but I think it is a valid question, so here's the answer:
query = "(SELECT id as id, name as name, reference as reference from subjects where name like $1)
UNION
(SELECT id as id, name as name, null as reference from elective_subjects where name like $1)"
binds = [ActiveRecord::Relation::QueryAttribute.new('name', search, ActiveRecord::Type::Text.new)]
result = ApplicationRecord.connection.exec_query(query, 'SQL', binds, prepare: true)
#subjects = result.rows
That's how you create and use a prepared statement in rails.
I have solved the issue by escaping the search string using following statement.
search = Mysql2::Client.escape(search)
I have the following table
product_id product_name image_path misc
---------- -------------- ------------ ------
1 flex http://firstpl... {"course_level_id":19,"group_id":"40067"}
2 Android http://firstpl... {"course_level_id":20,"group_id":"40072"}
So how can i retrieve the product_name,image_path & only "group_id" value like "40067" from "misc" column.
I tried below query but it returning 1/0 in Misc column.
SELECT product_name,image_path,misc REGEXP '(.*\"group_id\":*)' as Misc FROM ref_products where product_id=1
Any idea guys how to do it ?
The REGEXP function just returns 0 or 1. You will have to use other string functions.
Try this: substr(misc,locate('group_id',misc)+11,5) as Misc. But that assumes that group_id always has 5 characters.
So this is better: substring_index(substr(misc,locate('group_id',misc)+char_length('group_id')+3),'"',1) as Misc.
Here is a fiddle to show it working: http://sqlfiddle.com/#!2/ea02e/15
EDIT You can get rid of the +3 magic number by including the double quotes and colon in the strings like this:
substring_index(substr(misc,locate('"group_id":"',misc)+char_length('"group_id":"')),'"',1) as Misc
Since this question was asked MySQL have introduced support for the JSON data type.
In MySQL 5.7.8 (and up) you can query the actual JSON string stored in the column using JSON_EXTRACT() or the equivalent -> alias.
EG:
SELECT product_name, image_path, JSON_EXTRACT(misc,'$.group_id') AS `group_id`
FROM ref_products
WHERE product_id=1
See: https://dev.mysql.com/doc/refman/5.7/en/json.html
You can use a common_schema framework for MySQL (compatible with all MySQL >= 5.1) and then get what you need on this way:
SELECT x.product_name, x.image_path, common_schema.extract_json_value(x.misc,'/group_id') as group_id FROM your_table x
common_schema framework: https://code.google.com/p/common-schema/
Folks,
I have a column in MSSQl table as below:
| email |
-----------
suzuki#amc.com
yamaha#abc.co
harley#cbc.com
....
I want to write a query that will replace everything before the '#' in all the fields with a single work "cars". so the column should look:
| email |
-----------
cars#amc.com
cars#abc.co
cars#cbc.com
....
Any advice on how I can form this query ?
Many examples of solving this were already discussed here:
How do I replace a substring of a string before a specific character?
For example:
UPDATE YourTable set email = 'cars' + SUBSTRING(email, CHARINDEX('#',email), LEN(email))
Query:
SQLFIDDLEExample
UPDATE Table1
SET email = 'cars' +
SUBSTRING(email, CHARINDEX('#',email), LEN(email)-CHARINDEX('#',email)+1)
you try this instead ,
first select only the before # part from mail id
using this substring_index(email,'#',1)
then replace with cars
replace(email,substring_index(email,'#',1),'cars')
select replace(email,substring_index(email,'#',1),'cars') from table;