MYSQL Wildcard issue for my query - mysql

ive got an issue with the mysql wildcard.
Given is the following table:
id | name
--------------
1 | Marcel
2 | Marcel2
3 | Marcel3
Now i need to know how many entrys with the name Marcel are in the table.
SELECT id FROM 'users' WHERE name LIKE 'Marcel#'
--gives me **0** results
SELECT id FROM 'users' WHERE name LIKE 'Marcel_'
-- gives me just **1** result (**3** would be the solution)
What query could i use to identify how often the name + nr is in the table?

Use % wildcard:
SELECT id FROM `users` WHERE name LIKE 'Marcel%'
SqlFiddleDemo
% A substitute for zero or more characters
_ A substitute for a single character
So your:
SELECT id FROM 'users' WHERE name LIKE 'Marcel_' gives me just 1
result (3 would be the solution)
may be false see: SqlFiddleDemo because it gives you Marcel2 and Marcel3 (unless you have trailing whitespaces which I cannot see in example you've provided)

Name like '%Marcel%' Should work for you.

Related

How to use LIKE operator in MYSQL?

Write an SQL query to report the patient_id, patient_name all conditions of patients who have Type I Diabetes. Type I Diabetes always starts with DIAB1 prefix.
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| patient_id | int |
| patient_name | varchar |
| conditions | varchar |
+--------------+---------+
This table contains information of the patients in the hospital.
patient_id is the primary key for this table. conditions contains 0 or more code separated by spaces.
So this was my solution:
SELECT *
FROM Patients
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '%DIAB1%' ;
It worked correctly for all these conditions
patient_id
patient_name
conditions
1
Daniel
YFEV COUGH
2
Alice
3
Bob
DIAB100 MYOP
4
George
ACNE DIAB100
except for this condition
patient_id
patient_name
conditions
1
Daniel
SADIAB100
And in the solution it was shown that there is a space after 1st % which would give you the correct answer:
correct query:
SELECT *
FROM Patients
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '% DIAB1%' ;
So, can someone please explain why this query works for that particular condition (SADIAB100) and not the 1st query
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '% DIAB1%'
The problem this is trying to address is when a condition contains the keyword (DIAB1) - while you only want to match on the beginning of the keyword.
The naive approach fails, because it matches on "SADIAB100":
WHERE conditions LIKE '%DIAB1%'
So the workaround is to search for the keyword:
either at the beginning of the whole string (ie at the beginning of the first condition) ; that's what LIKE 'DIAB1%' does
or after another condition, in which case it is preceded by a space, so ' DIAB1%'
Hence:
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '% DIAB1%'
A slightly neater expression is:
WHERE CONCAT(' ', conditions) LIKE '% DIAB1%'
Bottom line: if you are using a relational database, you should not be storing multiple values in a single row.
Instead of a CSV-like format, you should have a separate table to store the conditions, with each value on a separate row, allowing you to leverage the powerful set-based features that your product offers.
creating a regex pattern to find the keyword 'DIAB1'
filtering on cases where it matches the above
with main as (
select
*, REGEXP_LIKE(conditions,'DIAB1') as is_relevant_patient
from <table_name>
)
select * from main where is_relevant_patient
fiddle test

Is it possible to search a column of IDs for 1 if other rows include IDs with 1 in them?

I have a MySQL database with a varchar column (although the column type can be changed if needed).
The column stores some ids separated with underscores like so:
Row 1: 1
Row 2: 1_2_3
Row 3: 10_2
Row 4: 4_5_1
Is there anyway in this structure to query that column for 1 and return all rows with 1 (but not Row 3 which contains 1 but the ID is 10).
To get the current results I am attempting to search the column LIKE %1%.
Or do I need to change the structure to achieve the result I want?
Maybe you can try:
select *
from t
where c like '1\_%'
or c like '%\_1'
or c like '%\_1\_%'
or c = '1'
You need to escape the underscore as \_, since SQL defines it as a wildcard and will match any character.
If we had a comma separator, then we could use MySQL FIND_IN_SET function.
We can use MySQL REPLACE function to change the underscores to commas,
e.g.
SELECT t.*
FROM t
WHERE FIND_IN_SET('1',REPLACE( t.id ,'_',','))
Reference:
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_replace
NOTE:
Storing underscore separated lists is an antipattern. See Chapter 2 of Bill Karwin's book "SQL Antipatterns: Avoiding the Pitfalls of Database Programming"
https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
With the operator like:
select * from tablename
where concat('_', id, '_') like '%#_1#_%' escape '#'
See the demo.
Results:
| id |
| ----- |
| 1 |
| 1_2_3 |
| 4_5_1 |

MySQL - REGEX Search word from string and matched word should be either alnum or numeric only

Question: If i pass any word in where clause then query should return only if passing word is alnum or num only using mysql regex.
I have a table where addresses.
address table
--------------------
id | name
--------------------
1 | 123 demo
--------------------
2 | 1st demo
--------------------
3 | 123
--------------------
4 | demo
Example 1
SELECT * FROM address WHERE name regexp '(^|[[:space:]])123([[:space:]]|$)'
Result: Row 1,3 should return. it works for me
Example 2
SELECT * FROM address WHERE name regexp '(^|[[:space:]])1st([[:space:]]|$)'
Result: Row 2 should return. it works for me
Example 3
SELECT * FROM address WHERE name regexp '(^|[[:space:]])demo([[:space:]]|$)'
Result: It should not return any row. but it return 1,2,4 row
Final : So if i pass "demo" in where clause then no result should return.
http://sqlfiddle.com/#!9/acc5c8/2
I want to recommend wordboundary syntax like this: REGEXP '[[:<:]]demo[[:>:]]'
http://sqlfiddle.com/#!9/d63e05/1
Honestly, if this were my project, I'd be doing a ctype_alnum() check on the search value before bothering to make a trip to the database. However, your requirement is:
only if passing word is alnum or num only using mysql regex
To ensure that the needle string in the query contains at least one number, add another check to the WHERE clause.
More specifically...
SELECT * FROM address WHERE address REGEXP '[[:<:]]demo[[:>:]]' AND 'demo' REGEXP '[0-9]'
This will return no rows as desired.

SQL query to select columns with exact like?

Consider this SQL table
id | name | numbers
------------------------
1 | bob | 1 3 5
2 | joe | 7 2 15
This query returns the whole table as its result:
SELECT * FROM table WHERE numbers LIKE '%5%'
Is there an SQL operator so that it only returns row 1 (only columns with the number 5)?
Use regexp with word boundaries. (But you should ideally follow Gordon's comment)
where numbers REGEXP '[[:<:]]5[[:>:]]'
It's a pity that you are not using the comma as a separator in your numbers column, because it would be possible to use the FIND_IN_SET function, but you can use it together with REPLACE, like this:
SELECT * FROM table WHERE FIND_IN_SET(5, REPLACE(numbers, ' ', ','));

Select two first characters and ignore duplicates

I'm currently working on a MySQL database that stores lots of unique postcodes. This is how it looks like:
postcode_id | postcode
------ | ------
1 | BA10EJ
2 | TR96PY
3 | TA64RD
4 | EX54NA
5 | EX167DT
I'd like to select the first couple characters and only list the unique ones, so if there are two EXs I just need to display EX once.
This is what I'm trying to get:
postcode
------
BA
TR
TA
EX
Select distinct substr(postcode,1,2)
from my_table;
Managed to solve my problem by using this query:
SELECT DISTINCT LEFT(postcode, 2) FROM cc_postcodes
Thank you all for your help!
This can be achieved by MySql left(str, len) function. This function returns the leftmost len characters from the string str, or NULL if any argument is NULL.
select distinct left(<mycolumn>, <no_of_chars>) as <myColumn> from <mytable>
To know more about MySql Left()
Use left() with SELECT DISTINCT to get the unique entries.
SELECT DISTINCT LEFT(postcode,2) FROM postcodes;
See this working SQL Fiddle