if have a mailing script that i've set to throttle domains i send to. the remaining domains that do not have a throttle rate set, get assigned a default rate. to find domains which do NOT match an existing throttled domain, i use this php:
$query = "SELECT * FROM `mailer_lists` ml JOIN `mailer_controller` mc";
$query .= " ON ml.project_name = mc.project_name";
$query .= " WHERE `email` NOT LIKE '%";
$query .= "" . implode("' OR '%", $throttle_domain) . "'";
echo "$query";
the output of the echo is:
SELECT * FROM `mailer_lists` ml JOIN `mailer_controller` mc ON ml.project_name = mc.project_name WHERE `email` NOT LIKE '%gmail.com' OR '%hotmail.com' OR '%yahoo.com' OR '%aol.com'
as far as i can tell the output looks perfectly fine. i ran a test query in phpmyadmin and only the first domain applies. anything after the OR is ignored.
is there something obviously wrong with this query that i'm missing? can't you use multiple OR statements while using the NOT LIKE statement?
I would do
where substring_index(`email`,'#',-1) not in ('yahoo.com','gmail.com')
and so on.
You're taking mySQL's "human language" approach too far. :) Each OR is interpreted as an expression of its own, not as a value to do a LIKE against.
Also, I think you want to use AND. Using OR will always apply to every row.
Try
(`email` NOT LIKE "%gmail.com")
AND (`email` NOT LIKE "%hotmail.com")
AND (`email` NOT LIKE "%yahoo.com") ....
You must repeat the field_name not like part :
SELECT *
FROM `mailer_lists` ml
JOIN `mailer_controller` mc ON ml.project_name = mc.project_name
WHERE
`email` NOT LIKE '%gmail.com'
and `email` NOT LIKE '%hotmail.com'
and `email` NOT LIKE '%yahoo.com'
and `email` NOT LIKE '%aol.com'
LIMIT 50
(And you probably have to use and, instead of or, between the conditions)
Related
In mysql I have something like:
$currentname = mysql_query("SELECT * FROM posts LIMIT $start, 5 WHERE ");
How can i do something like this below that works:
$currentname = mysql_query("SELECT * FROM posts LIMIT $start, 5 WHERE `title` LIKE '%{Hello world}%' || Where `text` LIKE '%{Hello World}%'");
Something like above that will actually work.
Try this:
$queryResult = mysql_query("SELECT * FROM posts WHERE `title` LIKE '%{Hello world}%' OR `text` LIKE '%{Hello World}% LIMIT $start, 5'");
$currentName = mysql_fetch_assoc($queryResult);
if you expect many results...
while($currentName = mysql_fetch_assoc($queryResult)) {
//your code here...
}
Replace || with OR and remove the extra WHERE that comes after it. In SQL, || is OR and && is AND. You can read more here.
Note: Please take time to read manuals, it absolutely helps.
You can use OR in MySql, and it is likely very suitable for most situations.
OR however has a slight disadvantage performance wise as for each OR query the whole query is ran again. I am no MySql performance guru, but it would seem UNION is better optimized. So in general, and at lest with more OR statements you should use a UNION like this:
SELECT your_union_result.* FROM
(
SELECT * FROM posts WHERE `title` LIKE '%{Hello world}%'
UNION
SELECT * FROM posts WHERE `text` LIKE '%{Hello World}%'
) AS your_union_result
ORDER BY your_union_result.order_column
LIMIT $start, 5
Please note: My version has a subquery. You need it in case you want to order the result or limit the total rows. You now have a few options to fetch the actual result.
You can fetch_assoc(), fetch_array() and so on row by row. It is unclear for me what you want as the actual result. The $currentname indicates a post or user name, but a limit of $start, 5, indicates you want a list.
Go ahead and read http://php.net/manual/en/function.mysql-fetch-array.php and the other fetch functions. If you need more help, please update your question to be a bit more specific.
I am using mysql to create a search function from a database, however from the way the rest of the program is designed the user must only return 1 result from the info they enter. That is fine for me to program errors and such but I am having trouble accepting multiple strings as inputs to select the data from the table?
How do I make people be able to enter a combination of multiple fields (firstname, phone) etc. and come up with the results that match them without having the empty fields skew the results? i.e(Phone number is blank so only returning people with blank phone numbers)?
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname]
At the moment above is what the query is and I am unsure of what function to use (AND, OR) any help would be appreciated. Thanks it advance.
Generally this is something you would handle in your programming language (seems to be PHP here), and only query for the fields you are provided. You could do that like so :
$wheres = array('1=1');
if($_SESSION['queryfname']){
$wheres[] = "`First_Name` = '{$_SESSION['queryfname']}'";
}
if($_SESSION['querypnumber']){
$wheres[] = "`Phone_Number` = '{$_SESSION['querypnumber']}'";
}
$sql = "
SELECT *
FROM `users`
WHERE " . implode($wheres,' AND ');
however if you are limited to doing it in your SQL, you could do something like this
SELECT
*
FROM `users`
WHERE
(
`First_Name` = '{$_SESSION['queryfname']}'
AND
`First_Name != ''
)
OR --Could also be AND
(
`Phone_Number` = '{$_SESSION['querypnumber']}'
AND
`Phone_Number` != ''
)
LIMIT 1
You can try the limit:
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname] LIMIT 1;
I am attempting to write a search algorithm, nothing too advanced but it isnt just WHERE field1 = 'searchtext'. I am trying to search all keywords across multiple fields.
I have done a bit of searching and it seems as though my take on the matter is not compliant with MySQL's use of 'IN' with other functions, however I cannot find anything that seems to suggest a better way either here on stackoverflow or using google on independant blogs and other tutorial sites.
$fields = array('type','suburb','postcode','address'); // Fields in db being searched
$queried = $db->real_escape_string($_REQUEST['keyword']); // Input from form
$keys = explode(" ",$queried); // Determine individual keywords
$sql = "SELECT * FROM `properties` WHERE "; // Beginning of SQL Statement
$frc = 0; // Field Counter
foreach($fields as $f){
$inner = ''; // Reset $inner each run
$irc = 0; // Reset Inner Counter each run
$frc++; // Increase Field Counter
if($frc != 1){ $sql .= " OR "; } // All except first runthrough
$sql .= "`".$f."` IN "; // `field` IN
foreach($keys as $k){
$irc++; // Increase inner counter
if($irc == 1){
$inner .= "('%".$k."%'"; // First Inner per run (aka each keyword)
}else{
$inner .= ", '%".$k."%'"; // All other Inners
}
}
$inner .= ")"; // Inner finishes run before reset
$sql .= $inner; // Add Inner to SQL ready for query
}
$sql .= ";"; // Clean finish to SQL statement
$SearchProperties = $db->query($sql); // Run Query
I have included commentary to help you understand my messy code and what I felt I was doing. The code is giving me the expected output, for example if I search the keyword "house" my output is as follows;
$queried = house 3064
$sql = SELECT * FROM `properties` WHERE `type` IN ('%house%', '%3064%') OR `suburb` IN ('%house%', '%3064%') OR `postcode` IN ('%house%', '%3064%') OR `address` IN ('%house%', '%3064%');
Within the type column there is house and townhouse, it should be able to hit both, and should hit anything with the postcode 3064 regardless of if it has house in another column (According to what I want to accomplish)
However after several hours of searching, although my output is as desired I don't believe it to be correct. Could anybody help shed some light on the CORRECT method of solving my quandry and WHY this does not work? I always like to understand and learn from these sort of misunderstandings.
Thank you for your help.
If you have wildcards, you want like rather than in:
SELECT *
FROM `properties`
WHERE (`type` LIKE '%house%') OR
(`suburb` LIKE '%house%') OR
(`postcode` LIKE '%house%') OR
(`address` LIKE '%house%');
However, I would strongly suggest that you investigate full text indexes (see here). The use of MATCH() may greatly simplify your efforts.
EDIT:
Your query is still incorrect. And you should still be using like:
SELECT *
FROM `properties`
WHERE (`type` LIKE '%house%' or type like '%3064%') OR
(`suburb` LIKE '%house%' or suburb like '%3064%') OR
(`postcode` LIKE '%house%' or postcode like '%3064%') OR
(`address` LIKE '%house%' or address like '%3064%');
Try change 'IN' to 'LIKE'.
For example
$queried = house
$sql = SELECT * FROM `properties` WHERE
`type` LIKE '%house%'
OR `suburb` LIKE '%house%'
OR `postcode` LIKE '%house%'
OR `address` LIKE '%house%';
If you have a several keywords, then you need change query.
For example
$queried = house 3064
$sql = SELECT * FROM `properties` WHERE
(`type` LIKE '%house%' AND `type` LIKE '%3064%')
OR (`suburb` LIKE '%house%' AND `suburb` LIKE '%3064%')
OR (`postcode` LIKE '%house%' AND `postcode` LIKE '%3064%')
OR (`address` LIKE '%house%' AND `address` LIKE '%3064%');
My users can search for an order by an address right now. What I would like to do is let them be able to search with multiple criteria. Let them search by address, city, state, etc etc.
I have tried using the following code, but it doesn't seem to work.
$sql = ("SELECT order_number, sitestreet FROM `PropertyInfo` WHERE `sitestreet` LIKE '%$street%' OR `sitecity` LIKE '%$city%' AND `user` LIKE '$user'");
$result = mysql_query($sql);
I don't think it's reading the value in $user cause it displays all orders for all users.
How can I make it possible to search for an order using multiple serach values?
Thank you!
Wrap your OR statements in parenthesis so it forms one top-level condition, the user is the other top-level condition:
$sql = '
SELECT
`order_number`,
`sitestreet`
FROM
`PropertyInfo`
WHERE
(
`sitestreet` LIKE "%'.$street.'%" OR
`sitecity` LIKE "%'.$city.'%"
) AND
`user` = '.$user;
Also note, you want a direct match to the user column, use = instead of LIKE. I am assuming that $user is a numeric ID...
How about trying like
$sql = ("SELECT order_number, sitestreet FROM PropertyInfo WHERE (sitestreet LIKE
'%$street%' OR sitecity LIKE '%$city%') AND user LIKE '$user'");
AND has a higher order of precedence than OR (see http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html for details). You need to wrap your OR statement in parentheses so it get evaluated as one statement, before the AND statement.
SELECT order_number, sitestreet
FROM `PropertyInfo`
WHERE (`sitestreet` LIKE '%$street%' OR `sitecity` LIKE '%$city%')
AND `user` LIKE '$user'
Try:
$sql = ("
SELECT order_number, sitestreet
FROM `PropertyInfo`
WHERE (`sitestreet` LIKE '%$street%'
OR `sitecity` LIKE '%$city%')
AND `user` LIKE '$user'");
You should group the ORs together. The way it is written I believe it is reading it as 'if Street matches, ignore any other conditions (OR), otherwise both city and user must match.
Also G molvi's point is good, unless you're looking for a pattern match, go with =
HTH
look at this table please
table
|id| |name| |order|
i must get the rows, where name = something and order = somevalue
so i write
select `id` from `table` where `name` = 'something' and `order` = 'somevalue'
but depend on php logic, sometimes i need to get all rows, where name = something, independently of order value. i don't want to change the query structure, because in practise there are many number of fields, and possible count of queries will become very big. so i want to save the structure of query, and when i need to select just by name, i want to write something like this:
select `id` from `table` where `name` = 'something' and `order` = any value
is it possible?
thanks
Well, it's kind of a hack, but if you really need to do this, it'll work like this:
select `id` from `table` where `name` = 'something' and `order` = `order`
Then you're just saying "wherever order is the same as itself", so it's always true.
No, this is not possible. You need to change the structure (optionally to a LIKE so you can use '%', but that's very ugly).
However, you don't need to write a different query to handle every possible combination. You can simply create the query dynamically:
//create base query
$query = "select `id` from `table` where `name` = 'something' ";
//add order if we need it
if ($use_order)
$query .= "and `order` = 'somevalue' ";
//repeat for any other optional part
Note that you should of course still take proper measures to avoid SQL injection and other security issues - I have not included this here in order to keep things simple.
If you are using bound parameters, it would be impossible.
If you just substitute the values, you can do the following:
select `id` from `table` where `name` = 'something' and `order` = `order`
This is a common theme with database queries - you need a variable query depending on how much filtering you wish to apply to the data it queries. You could go the route of having your query repeated as a string throughout your code, but that is bad practice as it increases the complexity of the code needlessly. Chances for errors occur if you need to change the query for some reason, and have to change it in multiple places as a result.
The better solution is to create a function which builds the query for you execute:
function buildMyQuery($name, $order = null) {
$sql = "SELECT `id` FROM `table` WHERE `name`='$name'";
if ($order != null) {
$sql .= " AND `order`='$order'";
}
return $sql;
}
You could then run this for just using the 'name' field:
$query = buildMyQuery("somename");
Or this for using both fields:
$query = buildMyQuery("somename", "someorder");
As someone mentioned above, this code is deliberately simplified and contains no contingency for possibly dangerous data passed in via $name or $order. You would need to use mysql_real_escape_string or something similar to clean the data first, at the beginning of the function before either piece of data is used.
Dynamic query generation is a fact of life as Byron says, so I would become accustomed to it now rather than using hack-ish workarounds.
I don't think you have any choice... Once you do a selection you can't "unfilter" and get more rows.
You should just use two queries-- either two independent queries, or one that selects on the name into a temp table, and then (optionally) one that further selects on the order attribute.
Like Chad said above, just set the column equal to itself. But be careful, on some platforms / install configurations, NULL != NULL:
select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'')
On reflection, I have a better answer. My colleague showed me a way this can be done.
My example...
Select rentals.* From rentals Where ((? = '') OR (user_id = ?))
The variables must be the same.
If they are both 5 for example, the first boolean will be false, but the second will be true, for the rows where the users id is 5.
If you require "all", setting as an empty string will result in all rows being seen to meet the where clause condition.
Can't you just use a not null query here?
select `id` from `table` where `name` = 'something' and `order` is not null;
You should be able to do it like this:
select `id` from `table` where `name` <>'' and `order` <>''
That will select anywhere that the value is not equal to blank.
$sql = "SELECT * FROM auctions WHERE id = id ";
if ($category !== "ANY") {
$sql .= "AND category = $category "; }
if ($subcategory !== "ANY") {
$sql .= "AND subcategory = $subcategory "; }
if ($country !== "ANY") {
$sql .= "AND country = $country "; }
$sql .= "ORDER BY $order $sort LIMIT $limit OFFSET $offset";