I am trying to write a select statement that uses several keywords to search by. For example
SELECT id FROM my_mod mm WHERE (mm.name LIKE '%joe%' OR mm.name LIKE '%jim%');
What I would like to do is in the return data have a extra column that counts the number of times that row matches one of the like statements.
So for the one above if there is a name jimjoe it would have a count of 2 or if the name is jim it would have a count of 1. Does anyone know of a way to do this?
I should also mention that I can't use temp tables.
SELECT id,
CASE
WHEN mm.name LIKE '%joe%'
AND mm.name LIKE '%jim%' THEN 2
ELSE 1
end AS cnt
FROM my_mod mm
WHERE mm.name LIKE '%joe%'
OR mm.name LIKE '%jim%'
Try this query -
SELECT
COUNT(IF(name LIKE '%joe%', 1, NULL)) joe_count,
COUNT(IF(name LIKE '%jim%', 1, NULL)) jim_count
FROM
my_mod
WHERE
name LIKE '%joe%' OR name LIKE '%jim%'
Try this
select t.id,count(*) FROM
((select id from my_mod where name like '%jim%')
union all
(select id from my_mod where name like '%joe%')) t group by t.
I check here how it works
Related
I have this MYSQL table named people with the columns: id|firstname|lastname|birthdate|phone.
I am quite new to MYSQL and I'm trying to UNION several SELECTs so that the result will look in the following way:
only the first 20 results must be shown
the first SELECT criteria is by the combination firstname+lastname+birthdate: WHERE (birthdate="1980-01-01") AND ((firstname LIKE "%john%") AND (lastname LIKE "%smith%"))
the second SELECT criteria is by the combination firstname+lastname: WHERE (firstname LIKE "%john%") AND (lastname LIKE "%smith%")
the third SELECT criteria is by phone: WHERE phone="0123456"
the output result must in fact have 3 columns: order|id|type; where "order" and "type" are alias columns
the exported ids must be unique: if the same id results from all the 3 SELECTs (or from more than one SELECT), then it must appear only once in the output table
the column "order" must have the value 1 for the results of the first SELECT, 2 for the 2nd SELECT and 3 for the last SELECT
if the same id value results from more than one SELECT, then its row must have the highest order value; where the highest order posible is 1, from the first SELECT
the alias column "type" must work like this: if an id results from the 1st SELECT, it's type value is "~firstname+lastname+birthdate~"; if an id results from the 2nd SELECT, it's type value is "~firstname+lastname~"; and finally if an id results from the 3rd SELECT, it's type value is "~phone~"
if the same id value results from more than one SELECT, the value on the "type" alias column must be a concatention between the SELECTs where that id was found (for example, if the same id resulted in all 3 SELECT queries then the value on the "type" column would be "~firstname+lastname+birthdate~~firstname+lastname~~phone~")
Is it possible to achieve such an output?
Here's something using CASE statements. I think you'll get into a mess with union statements, because of your order type statement. Hopefully I've understood what you're after - it's much easier if you post sample data! Anyway, even if this doesn't do exactly what you want, you get the idea....
[EDIT] I don't think you need the distinct, but I don't think it hurts, either...
SELECT DISTINCT
CASE WHEN birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN 1
WHEN firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN 2
WHEN phone='0123456'
THEN 3
END AS outputorder, -- avoid confusion of using an SQL keyword as a column name,
id,
CONCAT(
CASE
WHEN birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN CONCAT('~',firstname,'+',lastname,'+','~')
END ,
CASE WHEN firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN CONCAT('~',firstname,'+',lastname,'~')
END ,
CASE WHEN phone='0123456'
THEN CONCAT('~',phone,'~')
END
) -- end the concat
AS outputtype
FROM
mytable
WHERE
( birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%')
OR
(firstname LIKE '%john%' AND lastname LIKE '%smith%')
OR
phone='0123456'
ORDER by 1,2 LIMIT 20
In the end I did something like this and it worked just fine:
SELECT MIN(`ord`) AS `order` , `id` , GROUP_CONCAT(`spec`) as `type` FROM (
SELECT "1" AS `ord` , `id` , "~firstname+lastname+birthdate~" AS `spec` FROM `people` WHERE (`birthdate` = "1986-04-02") AND (`lastname` LIKE "%smith%") AND (`firstname` LIKE "%john%")
UNION
SELECT "2" AS `ord` , `id` , "~firstname+lastname~" AS `spec` FROM `people` WHERE (`lastname` LIKE "%smith%") AND (`firstname` LIKE "%john%")
UNION
SELECT "3" AS `ord` , `id` , "~phone~" AS `spec` FROM `people` WHERE (`phone`="0123456")
) final
GROUP BY final.`id`
ORDER BY `order` ASC
LIMIT 20
Thanks to mlinth for the alternative though...
I did some searching and from one question already posted on stackexchange, the answer was that it was not possible, but I figured to ask. I did not know if it was possible to form a SELECT query to dynamically select which columns will be displayed in a mysql SELECT statement result. Example:
Say I have column names Person, ID, Phone Number, Alt Number for this table:
John | 79 | 800-499-0000 | 800-499-5555
I would like to form a SELECT statement so that it will only pull down columns where string '800-499' is somewhere in the field. Thus the result from MySQL ideally would be:
800-499-0000 | 800-499-5555
The only problem is that I do not think dynamically selecting columns is possible.
Any help or confirmation is appreciated.
You could try something like:
select * from
(select concat(case when col1 like '%800-499-0000%' then concat('col1: ',col1,';') end,
case when col2 like '%800-499-0000%' then concat('col2: ',col1,';') end,
...
case when coln like '%800-499-0000%' then concat('coln: ',coln,';') end)
as search_results
from my_table) sq
where search_results is not null
Eddited to more accurate problem:
i have a table: id, supplierCode, propertyCode, specification. While doing search in products i would like to get products that specifications has a text like value1 and value2, so to get those products i would like an query sumething like this:
SELECT * FROM tbl WHERE (specification LIKE '%value1%' OR specification LIKE '%value2%') AND (those 2 got rows has the same supplierCode)
Or from other side of problem: Get all supplierCode's where whatever rows with same supplierCode has in the specification columns LIKE '%value1%' AND LIKE '%value2%'
Example:
id supplierCode propertyCode, specification
1 001234 11 i7-blabla
2 001234 13 15.3"
3 004321 15 i7-9761
4 004321 16 15.4"
5 003214 14 i7-15.3"
And if i'm searching for 'i7' and '15.3"' i could get 001234 and 003214 becouse they has i7 and 15.3" in their specifications
You can use the IN clause--definitely research thi problem a bit more, you would've definitely found a solution somewhere in the web.
SELECT * FROM tbl
WHERE specification IN ('value1', 'value2')
AND propertyCode = 'SOME_VALUE'
use LIKE instead of = sign
SELECT *
FROM tbl
WHERE (
specification LIKE CONCAT('%', value1, '%') OR
specification LIKE CONCAT('%', value2, '%')
) AND
propertyCode = valueHere
but if you are sure with the specification values use IN instead of OR (actually they are the same)
SELECT *
FROM tbl
WHERE specification IN ('value1','value2') AND
propertyCode = valueHere
you can use like keyword
pattern matching
SELECT * FROM tbl
WHERE (specification='%value1%' OR specification='%value2%')
group by propertyCode
$find = mysql_query("SELECT * FROM `tbl` WHERE (`specification` LIKE '%$value1%' OR `specification` LIKE '%$value2%') AND `propertyCode`='$propertycode'")or die(mysql_error());
$display = mysql_fetch_array($find);
Bare in mind you will need to change the PHP variables as you have not included any I have to presume you are looking for something like the above.
Also if you are looking to create a list then you will need to use a while statement on your fetch.
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)))
i am trying to sort mysql data with alphabeticaly like
A | B | C | D
when i click on B this query runs
select name from user order by 'b'
but result showing all records starting with a or c or d i want to show records only starting with b
thanks for help
i want to show records only starting with b
select name from user where name LIKE 'b%';
i am trying to sort MySQL data alphabeticaly
select name from user ORDER BY name;
i am trying to sort MySQL data in reverse alphabetic order
select name from user ORDER BY name desc;
but result showing all records
starting with a or c or d i want to
show records only starting with b
You should use WHERE in that case:
select name from user where name = 'b' order by name
If you want to allow regex, you can use the LIKE operator there too if you want. Example:
select name from user where name like 'b%' order by name
That will select records starting with b. Following query on the other hand will select all rows where b is found anywhere in the column:
select name from user where name like '%b%' order by name
You can use:
SELECT name FROM user WHERE name like 'b%' ORDER BY name
If you want to restrict the rows that are returned by a query, you need to use a WHERE clause, rather than an ORDER BY clause. Try
select name from user where name like 'b%'
You do not need to user where clause while ordering the data alphabetically.
here is my code
SELECT * FROM tbl_name ORDER BY field_name
that's it.
It return the data in alphabetical order ie; From A to Z.
:)
I had the same challenge, but after little research I came up with this and it gave me what I wanted, and I was able to overcome that path.
SELECT * from TABLE ORDER BY name
Wildcard Characters are used with like clause to sort records.
If we want to search a string which is starts with B then code is like the following:
select * from tablename where colname like 'B%' order by columnname ;
If we want to search a string which is ends with B then code is like the following:
select * from tablename where colname like '%B' order by columnname ;
If we want to search a string which is contains B then code is like the following:
select * from tablename where colname like '%B%' order by columnname ;
If we want to search a string in which second character is B then code is like the following:
select * from tablename where colname like '_B%' order by columnname ;
If we want to search a string in which third character is B then code is like the following:
select * from tablename where colname like '__B%' order by columnname ;
Note : one underscore for one character.
I try to sort data with query it working fine for me please try this:
select name from user order by name asc
Also try below query for search record by alphabetically
SELECT name FROM `user` WHERE `name` LIKE 'b%'
MySQL solution:
select Name from Employee order by Name ;
Order by will order the names from a to z.