MySQL QUERY condition - mysql

I try make search for my site. Example: have field name = city, if city is empty my query looks: SELECT * FROM TABLE WHERE CITY = ALL;
I don't know how to write: CITY = ALL correct, expression CITY is not null will be complicated because I should be remove =

Try this:
SELECT *
FROM Table
WHERE #SearchParam IS NULL OR City = #SearchParam
If his parameter #SearchParam is passed to the query with a NULL value then it will return all the data in the table, otherwise it will search for the cities with this parameter.

remove the where completely
SELECT * FROM TABLE
or
SELECT * FROM TABLE WHERE CITY = #searchstring or #searchstring is null;

If you don't care about very optimized queries, you can use a like operator compare with
City like '%#exp'
If exp is empty the query returns all Cities.
I personally do not recommend this :)
All the best

If you are getting them all, why have the WHERE clause in at all?
SELECT * FROM TABLE
Note, you should avoid using SELECT * whenever possible. As it is a waste of resources, always be explicit with your columns returned.

Maybe something like this?
SELECT * FROM TABLE WHERE (CITY = SOMETHING) OR (SOMETHING is null);

Related

how to pass multiple variables in WHERE ... IN in stored procedure? [duplicate]

I have a column in one of my table where I store multiple ids seperated by comma's.
Is there a way in which I can use this column's value in the "IN" clause of a query.
The column(city) has values like 6,7,8,16,21,2
I need to use as
select * from table where e_ID in (Select city from locations where e_Id=?)
I am satisfied with Crozin's answer, but I am open to suggestions, views and options.
Feel free to share your views.
Building on the FIND_IN_SET() example from #Jeremy Smith, you can do it with a join so you don't have to run a subquery.
SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?
This is known to perform very poorly, since it has to do table-scans, evaluating the FIND_IN_SET() function for every combination of rows in table and locations. It cannot make use of an index, and there's no way to improve it.
I know you said you are trying to make the best of a bad database design, but you must understand just how drastically bad this is.
Explanation: Suppose I were to ask you to look up everyone in a telephone book whose first, middle, or last initial is "J." There's no way the sorted order of the book helps in this case, since you have to scan every single page anyway.
The LIKE solution given by #fthiella has a similar problem with regards to performance. It cannot be indexed.
Also see my answer to Is storing a delimited list in a database column really that bad? for other pitfalls of this way of storing denormalized data.
If you can create a supplementary table to store an index, you can map the locations to each entry in the city list:
CREATE TABLE location2city (
location INT,
city INT,
PRIMARY KEY (location, city)
);
Assuming you have a lookup table for all possible cities (not just those mentioned in the table) you can bear the inefficiency one time to produce the mapping:
INSERT INTO location2city (location, city)
SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
ON FIND_IN_SET(c.e_ID, l.city) > 0;
Now you can run a much more efficient query to find entries in your table:
SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;
This can make use of an index. Now you just need to take care that any INSERT/UPDATE/DELETE of rows in locations also inserts the corresponding mapping rows in location2city.
From MySQL's point of view you're not storing multiple ids separated by comma - you're storing a text value, which has the exact same meaing as "Hello World" or "I like cakes!" - i.e. it doesn't have any meaing.
What you have to do is to create a separated table that will link two objects from the database together. Read more about many-to-many or one-to-many (depending on your requirements) relationships in SQL-based databases.
Rather than use IN on your query, use FIND_IN_SET (docs):
SELECT * FROM table
WHERE 0 < FIND_IN_SET(e_ID, (
SELECT city FROM locations WHERE e_ID=?))
The usual caveats about first form normalization apply (the database shouldn't store multiple values in a single column), but if you're stuck with it, then the above statement should help.
This does not use IN clause, but it should do what you need:
Select *
from table
where
CONCAT(',', (Select city from locations where e_Id=?), ',')
LIKE
CONCAT('%,', e_ID, ',%')
but you have to make sure that e_ID does not contain any commas or any jolly character.
e.g.
CONCAT(',', '6,7,8,16,21,2', ',') returns ',6,7,8,16,21,2,'
e_ID=1 --> ',6,7,8,16,21,2,' LIKE '%,1,%' ? FALSE
e_ID=6 --> ',6,7,8,16,21,2,' LIKE '%,6,%' ? TRUE
e_ID=21 --> ',6,7,8,16,21,2,' LIKE '%,21,%' ? TRUE
e_ID=2 --> ',6,7,8,16,21,2,' LIKE '%,2,%' ? TRUE
e_ID=3 --> ',6,7,8,16,21,2,' LIKE '%,3,%' ? FALSE
etc.
Don't know if this is what you want to accomplish. With MySQL there is feature to concatenate values from a group GROUP_CONCAT
You can try something like this:
select * from table where e_ID in (Select GROUP_CONCAT(city SEPARATOR ',') from locations where e_Id=?)
this one in for oracle ..here string concatenation is done by wm_concat
select * from table where e_ID in (Select wm_concat(city) from locations where e_Id=?)
yes i agree with raheel shan .. in order put this "in" clause we need to make that column into row below code one do that job.
select * from table where to_char(e_ID)
in (
select substr(city,instr(city,',',1,rownum)+1,instr(city,',',1,rownum+1)-instr(city,',',1,rownum)-1) from
(
select ','||WM_CONCAT(city)||',' city,length(WM_CONCAT(city))-length(replace(WM_CONCAT(city),','))+1 CNT from locations where e_Id=? ) TST
,ALL_OBJECTS OBJ where TST.CNT>=rownum
) ;
you should use
FIND_IN_SET Returns position of value in string of comma-separated values
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
You need to "SPLIT" the city column values. It will be like:
SELECT *
FROM table
WHERE e_ID IN (SELECT TO_NUMBER(
SPLIT_STR(city /*string*/
, ',' /*delimiter*/
, 1 /*start_position*/
)
)
FROM locations);
You can read more about the MySQL split_str function here: http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
Also, I have used the TO_NUMBER function of Oracle here. Please replace it with a proper MySQL function.
IN takes rows so taking comma seperated column for search will not do what you want but if you provide data like this ('1','2','3') this will work but you can not save data like this in your field whatever you insert in the column it will take the whole thing as a string.
You can create a prepared statement dynamically like this
set #sql = concat('select * from city where city_id in (',
(select cities from location where location_id = 3),
')');
prepare in_stmt from #sql;
execute in_stmt;
deallocate prepare in_stmt;
Ref: Use a comma-separated string in an IN () in MySQL
Recently I faced the same problem and this is how I resolved it.
It worked for me, hope this is what you were looking for.
select * from table_name t where (select (CONCAT(',',(Select city from locations l where l.e_Id=?),',')) as city_string) LIKE CONCAT('%,',t.e_ID,',%');
Example: It will look like this
select * from table_name t where ',6,7,8,16,21,2,' LIKE '%,2,%';

Mysql select column with concat

i want some correction here. i want to select all people with name fred in database
Here's my query:
SELECT * FROM tdble WHERE CONCAT(name) LIKE CONCAT('%', REPLACE('fred', '')'%')
What you are asking can be simply achieved by either using the "=" operator of the wildcard operator "like" statement.
If you wish to find all records that have an exact match to the name 'Fred' then you should model your query as so:
Select * From tdble Where Name = 'fred'
However, if you want to get all results where the names have 'fred' included in it somewhere use the wildcard operator.
Select * From tdble Where Name like '%fred%'
Also you can further model your query to know where exactly in which form you want 'fred' to appear. Example if you want 'Fred' to be as the last characters of your name string, for instance you wish to get names which ends with fred then model your query like this:
Select * From tdble Where Name like '%fred'
(you will get results like 'alfred', provided there is an alfred in your table)
However if you wish to get all names that begin with fred, model the query like this:
Select * From tdble Where Name like 'fred%'
(you will get results like 'fredinane', provided there is a fredinane in your table)
Cheers
If you want to fetch record with name 'fred', you can simply do Select * from TableName Where Name = 'fred'.
If you want to fetch records which their names' string contain 'fred', you have to use select * from TableName where Name like '%fred%'

Why doesn't this LIKE query return any results?

I made table copied from W3schools 2015 ... Here's some of the data:
here the columns and data types i used as follows.
CustomerID = int
CustomerName = varchar
ContactName = varchar
Address = varchar
City = varchar
PostalCode = varchar
Country = text
When i used the following query i got the actual result.
SELECT * FROM Customers WHERE Country LIKE 'U%'; SELECT * FROM Customers WHERE Country LIKE 'M%'; SELECT * FROM Customers WHERE Country LIKE 'G%';
Now the problem was that When i used the following query, i weren't getting actual result.
SELECT * FROM Customers WHERE Country LIKE 's%';
i didn't see any row !!
But We should have seen the following output,
why ?? can anybody explain pls...
Moreover I am totally in Novice phase..
Thanks in Advance
May be,
This is Because of Your Country Column Starting with 'S'(which we think) are not really Starting with 'S', May be it's first charter is a Space.(Just A Guess)
so, For this Case you can try Once,
SELECT * FROM Customers WHERE rtrim(ltrim(Country)) LIKE 's%';
or
SELECT * FROM Customers WHERE replace(Country,' ','') LIKE 's%';
See How can I search (case-insensitive) in a column using LIKE wildcard?

How do I select all rows in a MySQL column

This seems to be an easy question but I can't for the life of me find an answer. How do I select all rows in a column regardless of value? For instance if I want everything in the column location:
"SELECT * FROM whateverTable WHERE id='$id' AND date='$date' AND location='I don't care, return everything'"
Keep in mind that I need location in there because I'm getting a dynamic URL query to this database, otherwise I would have just left it out.
Edit
I've read some of the answers and shame on me for not making myself clearer. I'm trying to see if a MySQL query where you can select every row in a column is possible without the need for this:
if ($location == '') {
"SELECT * FROM whateverTable WHERE id='$id' AND date='$date'"
} else {
"SELECT * FROM whateverTable WHERE id='$id' AND date='$date' AND location='$location'"
}
Rather than hacking up my code like that (because I have a hell of alot more query clauses in my real code), I'm trying to see if something like this is possible :
"SELECT * FROM whateverTable WHERE id='$id' AND date='$date' AND location='%'"
or this:
"SELECT * FROM whateverTable WHERE id='$id' AND date='$date' AND location='.*'"
But I'm not having any luck. If it's not, I'll just move on. Sorry for not making myself clearer
As you said in your question, you should build the query dynamically and just omit that field. The query would then become:
SELECT * FROM whateverTable
WHERE id = '$id'
AND date = '$date'
If you can't do that for some reason, you could try something like this:
SELECT * FROM whateverTable
WHERE id = '$id'
AND date = '$date'
AND (location='$location' OR '$location' = '')
Setting $location to the empty string will cause all locations to be returned.
And don't forget to correctly escape your strings to avoid SQL injection attacks.
SELECT location FROM whateverTable will return you every single row/value in the location column.
Add your where clause if you want to start filtering the results down.
If you're dynamically building the query just check if location is null or the empty string and then omit that part of the query.
Replace equal symbol : "=" by LIKE
SELECT * FROM whateverTable WHERE id='$id' AND date='$date' AND location LIKE '%'
I think you're looking for a sub query?
SELECT * FROM whateverTable WHERE location IN (SELECT location FROM whateverTable);

"Merge" IN and LIKE operator in Mysql

I've a problem and I'm guessing if there's a better way to achieve my goal. I've this query in Mysql to retrieve some rows:
SELECT *
FROM table
WHERE field IN ('V','S','G','B')
What I would like to do is to run a query that retrieve the rows where the field has value LIKE those in the IN list. I know that the trivial way is to use this query:
SELECT *
FROM table
WHERE field LIKE '%V%' OR field LIKE '%S%' OR
field LIKE '%G%' OR field LIKE '%B%'
What I want to know is there's an operator that do this or at least, if that operator does not exist, a better way to write the query.
Thanks to everyone that will help me.
Put the values in a table (Params) then use
SELECT *
FROM table
WHERE EXISTS (
SELECT *
FROM Params
WHERE table.field LIKE '%' + Params.col + '%'
);
Consider also putting the wildcard characters into the values in the Params table.