I know of the functions such as: JSON_SEARCH() and JSON_EXTRACT() etc. This issue is that I am searching for a key in a json string that is not standardized. for example:
SELECT
*
FROM
users
and the results could be something like this:
+---------------------------------------------+
| name | last | data |
+------+------+-------------------------------+
| john | doe | {"acctNum": "123"} |
+------+------+-------------------------------+
| john | doe | {"data":{ "acctNum": "123" }} |
+------+------+-------------------------------+
| jane | doe | {"data":{ "acctNum": "1234" }}|
+------+------+-------------------------------+
so in this example I want to get john doe with the acctNum of 123. but, also, the location of the acctNum key is different. I have seen here that you can use: JSON_SEARCH(data, $**.acctNum) but I get empty results,
In an ideal world what I would like is:
SELECT * FROM users WHERE JSON_EXTRACT(data, "$**.acctNum") = 123
and receive
+---------------------------------------------+
| name | last | data |
+------+------+-------------------------------+
| john | doe | {"acctNum": "123"} |
+------+------+-------------------------------+
| john | doe | {"data":{ "acctNum": "123" }} |
+------+------+-------------------------------+
also that in the link that is above finding the key acctNum could be extremely nested.
I had tried using the regexp with SELECT * FROM users WHERE data REGEXP '123'; but as you could imagine then the user jane doe will be matched as well
Search a defined value at any path:
SELECT *
FROM users
WHERE JSON_SEARCH(data, 'one', 123);
Search a defined value at a defined path:
SELECT *
FROM users
WHERE JSON_SEARCH(data, 'one', 123) = '$.acctNum'; -- or '$.data.acctNum'
Search a defined property name and value at any path:
SELECT *
FROM users
WHERE JSON_SEARCH(data, 'all', 123) LIKE '%.acctNum"%';
fiddle
Related
I currently have a table with columns for "field_type" (username, city, state), "user_id", and "value". The user_id column obviously has lots of repeats. I'd like to merge the city and state data into a single "location" field_type value. I need something that will:
for every integer in the user_id column:
-check if there exist corresponding (not null) table rows for field_type "city" and "state"
-if yes, insert a new row into the table with field_type "location" which concatenates the corresponding city and state values for that user_id
I haven't worked with MySQL much so I don't really know where to start. I've tried to simplify the problem a bit - it's actually a somewhat more complicated wordpress table and I'm trying to reformat the data to be compatible with a new plugin, but this covers the basics of what has to happen so I should hopefully be able to extrapolate an actual solution from the answers. Thanks for any pointers!
Edit: Current structure looks like this:
|-id (key)-|- field_type -|- user_id -|- value -|
| 1 | username | 1 | Joe |
| 2 | city | 1 | Albany |
| 3 | state | 1 | NY |
| 4 | username | 2 | Bob |
| 5 | city | 2 | Toledo |
| 6 | state | 2 | OH |
And I would like to get something like this:
|-id (key)-|- field_type -|- user_id -|- value ---------|
| 1 | username | 1 | Joe |
| 2 | city | 1 | Albany |
| 3 | state | 1 | NY |
| 4 | username | 2 | Bob |
| 5 | city | 2 | Toledo |
| 6 | state | 2 | OH |
| 7 | location | 1 | Albany, NY |
| 8 | location | 2 | Toledo, OH |
Duplicate user_id values are how it's supposed to work, so they don't need to be removed.
You could use an INSERT ... SELECT query to do this:
INSERT INTO yourtable
SELECT 'location' AS field_type, t1.user_id, CONCAT(t1.value, ' ', t2.value) AS value
FROM yourtable t1
JOIN yourtable t2 ON t2.user_id = t1.user_id AND t1.field_type = 'city' AND t2.field_type = 'state'
WHERE t1.value IS NOT NULL AND t2.value IS NOT NULL
Demo on dbfiddle
Since you are mentioned that there are duplicates with the same user_id.
I don't think inserting a new row will be a good idea.
So have written an update query to update the existing data.
You can later cleanup the duplciates.
UPDATE your_table SET locations = CONCAT_WS('-', state, city) where city is not null or state is not null
I just have a quick question about how to do something, but also about whether or not this is even possible in the first place. I've tried to find an answer online, but got no success.
I'll create a very simplified scenario that's not necessarily what I want to do precisely, but it's a pretty good example. Let's say that I have this table
Users
----------------------------------------------
| ID | FirstName | LastName | Username | ... |
|----|-----------|----------|----------|-----|
| 1| John | Doe | jdoe | ... |
| 2| James | Smith | jsmith | ... |
| 3| Jane | Fisher | jfisher | ... |
| x| ... | ... | ... | ... |
----------------------------------------------
Let's say that I want to create a query to show only the FirstName and LastName, but as a full name.
I could do:
SELECT Users.FirstName, Users.LastName
FROM Users
WHERE ID > 2
What I want however is something that would give me FirstName and LastName as one column that I'd present like this:
(Users.FirstName, Users.LastName) AS 'Full Name'
Therefore, I'd get something like:
Users
---------------------------------------
| ID | Full Name | Username | ... |
|----|---------------|----------|-----|
| 1| John Doe | jdoe | ... |
| 2| James Smith | jsmith | ... |
| 3| Jane Fisher | jfisher | ... |
| x| ... | ... | ... |
---------------------------------------
Of course, in my real query, I'd be joining a bit more than just 2 columns, but I think you get the point. So is this possible? If so, how can I do it.
SELECT first_name + ' ' + last_name as full_name from users
in Oracle
SELECT first_name || ' ' || last_name full_name from users
edit: maybe if you are having data type issues - you could force it to think it's a string - something like
SELECT '' + first_name + ' ' + last_name from users
You are using MySQL. While the standard string concatenation operator is ||, it doesn't work with MySQL. Use the function CONCAT_WS:
select concat_ws(' ', firstname, lastname)
from mytable;
(You could also use the function CONCAT, but I prefer CONCAT_WS in this situation.)
Here is the docs: https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_concat-ws
I have a table like this
+-----+------------------+
| id | name |
+-----+------------------+
| 1 | John;Black;Mike |
+-----+------------------+
| 2 | White;Mike;John |
+-----+------------------+
| 3 | Jacob;Mike |
+-----+------------------+
| 4 | Will;Mason;Mike |
+-----+------------------+
as result of
SELECT * FROM people WHERE name LIKE '%Mike%';
Is there any query on how to update specific name Mike to Michael without updating a whole value. like John;Black;Mike to John,Black,Michael in all rows automatically.
You could use replace
update people
set name = replace( name, 'Mike', 'Michael')
where name LIKE '%Mike%';
anyway you should avoid storing comma separated value .. you should think to a proper normalized table for this data ..
I got table called 'pet' have the following values
id | name | nickname | dateofborn |
1 | test | jhon | 2009 |
2 | test2| test | 2010 |
3 | mike | NULL | 2010 |
3 | jhon | testor | 2011 |
I want to select all of columns that contain 'test' value either in name column or nickname column so i have this query didn't actually work for me:
SELECT * FROM pet WHERE name='test' OR nickname= 'test'
note that I exactly want test value not testor.
The query is right, I think you have some problems with your Table.
But try like below:
USE [yourDB es: animals];
SELECT * FROM [yourDB].pet WHERE (name='test' OR nickname='test');
try this.
SELECT * FROM pet WHERE name like 'test%' OR nickname like 'test'
I can't figure out what's wrong with this query. I just want to search in a specific genre, but this query gives me results of other genres. Would really like some help. This code is for my first site built in php.
SELECT *
FROM news
WHERE (titel LIKE '%keyword%') AND genre='politics'
First, I'd suggest reading up on pattern matching in MySQL. The documentation link is: http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html
SQL pattern matching enables you to use “_” to match any single character and “%” to match an arbitrary number of characters (including zero characters). In MySQL, SQL patterns are case-insensitive by default. Some examples are shown here. You do not use = or <> when you use SQL patterns; use the LIKE or NOT LIKE comparison operators instead.
Examples
To find names beginning with “b”:
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
To find names ending with “fy”:
mysql> SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
To find names containing a “w”:
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
To find names containing exactly five characters, use five instances of the “_” pattern character:
mysql> SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Your modified query
So, you want your query to select rows from the NEWS table and select everything where the TITLE is like a keyword and GENRE is equal to a particular string.
Following is how I would structure your query. Performance considerations are not present in this query, but you may want to investigate indexes and other performance enhancers if this is a frequent query on a large table.
Originally, you are using:
SELECT * FROM news WHERE (title LIKE '%keyword%') AND genre='politics'
Option 1:
SELECT *
FROM news
WHERE
title LIKE '%keyword%'
AND
genre = 'politics';
Option 2:
You should think about where your input is coming from and if you need to parameterize the fields before you insert them into your query. Using parameters can lead to cleaner, more flexible code as well providing security and type checking.
Try something like this. This untested code, so there might be some syntax issues, but it should be close.
private string title = "%title%";
private string genre = "genre";
using (MySqlConnection con = new MySqlConnection(connectionString))
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = con;
cmd.CommandText
= "SELECT * FROM NEWS WHERE TITLE LIKE '#title' AND GENRE = #genre; ";
cmd.Parameters.AddWithValue("#title", title);
cmd.Parameters.AddWithValue("#genre", genre);
using (MySqlDataReader drd = cmd.ExecuteReader())
{
while (drd.Read())
{
// Read from data reader
}
}
}
}