MySQL LIKE on Subquery - mysql

I am writing a query where I am trying to pull out values based on a portion of a subquery and can't seem to work out how to get the needed values.
The table has only a half-dozen entries containing author names but in some instances, there is more than one author in the field and I need to get their separate individual biographies. Right now this gives no errors but it is pulling up only the single entry that contains both author names rather than the two that contain the actual biographies. I need only the two single-name entries, not the one containing both but it's giving the opposite.
AuthorName has something like this:
Joe Blow
Jane Doe
Jow Blow and Jane Doe
and here is the query
SELECT a.`ID` AS AuthorID, `AuthorName`, `AuthorPhoto`, `AuthorBio`, `Email`,
FROM authorbiographies a
WHERE `AuthorName` LIKE CONCAT('%',(
SELECT `AuthorName` )
FROM authorbiographies WHERE `AuthorName` LIKE '% and %),'%'
)
AND `ID` <> 3

This can be solved by joining a derived tables of all authornames that don't include and with a derived table of all authornames that do include and, as long as the first authorname is part of the second:
SELECT a1.id, a1.authorname, a1.authorbio
FROM (SELECT *
FROM authorbiographies
WHERE authorname NOT LIKE '% and %'
) a1
JOIN (SELECT *
FROM authorbiographies
WHERE authorname like '% and %'
) a2 on a2.authorname LIKE concat('%', a1.authorname, '%')
Output (for your sample)
id authorname authorbio
1 Joe Blow has lived a long time
2 Jane Doe wrote several books
Demo on SQLFiddle

Doesn't this do what you want?
SELECT ab.*
FROM authorbiographies ab
WHERE ab.authorname NOT LIKE '% and %';
You seem to just want to pick out the rows that do not have ' and ' in them.

Related

Query to check if a certain row has 2 words

How to return rows where a column has 2 words (that is, strings separated by a space) in it?
It must be purely using SQL.
SELECT * FROM table WHERE name (has 2 strings in it);
I dont know the names when querying. Its a big dataset. I only have to check if the name contains a spacebar basically (from a comment).
If you want to distinguish names that have two parts from one-part and three-plus-part names, you can use regular expression:
SELECT * FROM my_table WHERE name REGEXP '^[^ ]+[ ]+[^ ]+$'
This regular expression matches when the entire string consists of two non-empty parts containing no spaces, with one or more space separating them.
This perfectly works for me
You can use 'AND' condition and Like Operator with wildcards (%).
SELECT * FROM table_name WHERE name LIKE '%Word1%' AND name LIKE '%Word2%'
How about simply:
...
WHERE [name] LIKE '%Word1%'
AND [name] LIKE '%Word2%'
SELECT * FROM table WHERE concat(' ',name,' ') like '% str1 %'
AND concat(' ',name,' ') like '% str2 %'
The extra blanks are there to separate words.
You can use the following technique
mysql> select length('first name')-length(replace('first name',' ','')) as diff;
+------+
| diff |
+------+
| 1 |
+------+
i.e. get the difference of actual name and the name after replacing space, and if its 1 then you have the value as firstname lastname
So the query may look like
select * from table
where
length(col_name)-length(replace(col_name,' ','')) = 1
Use % between words.
Example:
SELECT * FROM Table WHERE Col LIKE '%word1%word2%'
SELECT * FROM table_name WHERE name LIKE '% %'

Find the all customer names consisting of three or more words (for example King George V)

schema:
customers(name, mailid, city)
What to find:
Find all customer names consisting of three or more words (for example King George V).
What I tried:
select name from customers
where name like
'%[A-Za-z0-9][A-Za-z0-9]% %[A-Za-z0-9][A-Za-z0-9]% %[A-Za-z0-9][A-Za-z0-9]%'
what is surprising me:
If I am trying for two words (removing the last %[A-Za-z0-9]% from my query), its working fine but its not working for three words :(
MySQL Solution:
If a name has words separated by space character, then,
Try the following:
select name from customers
where ( length( name )
-
length( replace( name, ' ', '' ) ) + 1
) >= 3
In t-sql, the like clause can contain multiple wild card checks - eg:
SELECT * FROM Customers WHERE Name like '% % %'
will return those Names where two spaces are contained.
If you are consistent with the spacing between names, you could use this logic
SELECT LENGTH(name)-LENGTH(REPLACE(name,' ',''))
FROM customers
Or you can try this too if your sql dont have length function ( which is the situation I have when I'm doing an online exercies...) Inspired by answers above
SELECT name FROM customers WHERE (replace(name,' ','*')) LIKE '%*%*%'

SQL search in multitable

i have two tables: songs and singers
and this my query:
Select * FROM (
SELECT
idx,
name,
IDsinger,
permission,
(name LIKE '%XXX%') As relevancy,
'table1' As t
FROM `songs`
where
isActive<>'0' AND name LIKE '%XXX%'
UNION
SELECT
idx,
name,
CreationDate,
permission,
(name LIKE '%XXX%') As relevancy,
'table2' As t
FROM `singers`
WHERE isActive<>'0' AND name LIKE '%XXX%'
) AS X
order by relevancy LIMIT 10
The problem is if i write "akon lonely" is not found result.
But if i write "akon" or "lonely" is found result.
And i would love suggestions for improving query..
Thanks
Your result is correct. AKON is a singer and Lonely is the song. Neither the Song or the Singer is called Akon lonely.
Sounds like you are trying to do a more complicated form of searching like contains.
http://technet.microsoft.com/en-us/library/ms187787.aspx
You could try
name like '%' + #xxx + '%' or #xxx like '%' + name + '%'

search in mysql fields

I need to have a select statement that matches records partially from a field containing full names.
If a record contains john, it will display records with john, johnson, johnsmith etc. john could be anywhere within name
select
name_field
from
my_table
where
name_field like '%john%'
Update:
For the question
Do you mean to ask that "How to find, if name_field value of row1 matches full or partial with the same field value from other row2 to rowN?"
You replied "this is exactly what i need".
The following solution may be helpful to you:
select
t.name_field_id, t.name_field as 'name_value',
d.name_field_id as 'id_of_dup', d.name_field as 'dup_in'
from
my_table t,
my_table d
where
d.name_field != t.name_field
and d.name_field like concat( '%', t.name_field, '%' )
order by name_value, dup_in;

Ordering a Union Query in MS Access SQL

OK I have a particularly nasty union ordering problem so any help would be appreciated.
The scenario is this:
Member Table with the following records (actual data):
REI882
YUI987
POBO37
NUBS26
BTBU12
MZBY10
TYBW54
(These are listed in the order I want them back from my query.)
There are a number of business rules about the construction of these MemberIDs which I believe are unrelated to the sort. They're historic and set in stone. I'm stuck with them. They indicate seniority of the member.
The ordering is done from the last 4 characters in the ID, ascending. The first two characters of the ID are completely meaningless as far as the sort is concerned.
So the topmost possible record is ??A001 (most senior) and the lowest possible record is ??ZZ99 (least senior).
When I query my member table the list I get back must display most senior at top... Obviously a standard sort does not work. This is what I have to date:
The first of these queries deals with sorting members whose ID only has 1 leading letter. The second deals with those with 2 leading letters.
SELECT * FROM (
SELECT Member.ID
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],4,1)))=-1)) **check the 4th character is a digit
ORDER BY (Mid([Member.ID],3,1)), (Mid([Member.ID],4,1)), (Mid([Member.ID],5,1)), (Mid([Member.ID],6,1))
) t1
UNION
SELECT * FROM (
SELECT Member.ID
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],4,1)))=0)) **check the 4th character is a letter
ORDER BY (Mid([Member.ID],3,1)), (Mid([Member.ID],4,1)), (Mid([Member.ID],5,1)), (Mid([Member.ID],6,1))
) t2
But I get CRAZY results with the union! If I run each of the selects individually - no problem my funky (heavily reliant on some nasty string manipulation in access!) sort works exactly as I want it.
I understand this is pretty complicated but I hope I've explained it clearly and that someone is up for some kudos for figuring it out!!!
edit: The result from my query is seemingly random:
YUI987
MZBY10
NUBS26
BTBU12
REI882
POBO37
TYBW54
ORDER BY in a SELECT statement that UNION with another SELECT is not correct.
See Specifying a conditional order here
You can use this:
SELECT ID FROM(
(SELECT Member.ID,1 AS T,Left([Member.ID],2) AS Part1, Right([Member.ID],4) AS Part2
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],3,1)))=-1)))
UNION
(SELECT Member.ID,2 AS T,Left([Member.ID],3) AS Part1, Right([Member.ID],3) AS Part2
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],4,1)))=-1) and ((IsNumeric(Mid([Member.ID],3,1)))=0)))
UNION
(SELECT Member.ID,3 AS T,Left([Member.ID],4) AS Part1, Right([Member.ID],2) AS Part2
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],5,1)))=-1) and ((IsNumeric(Mid([Member.ID],4,1)))=0)))
ORDER BY T,Part1,Part2)
#Justin Kirk: I don't know what is your problem exactly. But I hope it can help you
Why are you not using the RIGHT function.
Something like
SELECT ID
FROM (
SELECT ID
FROM (
SELECT Member.ID
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],4,1)))=-1)) **check the 4th character is a digit
) t1
UNION
SELECT ID
FROM (
SELECT Member.ID
FROM Member
WHERE (((IsNumeric(Mid([Member.ID],4,1)))=0)) **check the 4th character is a letter
) t2
) t3
ORDER BY RIGHT(ID,4)
How about skipping the UNION?
SELECT members.ID
FROM members
ORDER BY Right([ID],3), Right(id,4)
Based on the new rules, this mess may work.
SELECT
Len(IIf([textId] Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Left([textid],2),
IIf([textId] Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Left([textid],3),
IIf([textId] Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Left([textid],4),"_")))) AS Ln,
IIf(textId Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Left(textid,2),
IIf(textId Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Left(textid,3),
IIf(textId Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Left(textid,4),"_"))) AS Alpha,
IIf(textId Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Val(Right(textid,4)),
IIf(textId Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Val(Right(textid,3)),
IIf(textId Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Val(Right(textid,2)),0))) AS Numbr,
table.textid
FROM table
ORDER BY
Len(IIf([textId] Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Left([textid],2),
IIf([textId] Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Left([textid],3),
IIf([textId] Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Left([textid],4),"_")))),
IIf(textId Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Left(textid,2),
IIf(textId Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Left(textid,3),
IIf(textId Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Left(textid,4),"_"))),
IIf(textId Like "[a-z][a-z][0-9][0-9][0-9][0-9]",Val(Right(textid,4)),
IIf(textId Like "[a-z][a-z][a-z][0-9][0-9][0-9]",Val(Right(textid,3)),
IIf(textId Like "[a-z][a-z][a-z][a-z][0-9][0-9]",Val(Right(textid,2)),0)))