Select nested AND OR. How? - mysql

Below I have an SQL query that servers as a login script for users who choose to either type in their username or email.
I've noticed that even though it seems it would check for either or as a login credential in doesn't.
username1 OR username1#email.com = Only really looking up by username
SELECT *
FROM tblaccount
WHERE acc_user='username1' OR acc_email='username1#email.com'
AND acc_password='letmein1' AND acc_confirmed='1' AND acc_active='1'
...if I alter it to...
username0 OR username1#email.com = It does not return a record.
Any thoughts?

Put some parentheses around those conditions with OR:
SELECT * FROM tblaccount
WHERE (acc_user = 'username1' OR acc_email = 'username1#email.com' )
AND acc_password = 'letmein1'
AND acc_confirmed = '1'
AND acc_active = '1';

Mahmoud's solution is correct. You will have to read the operator precedence in mysql.
http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html
As OR has low precedence than the AND, you will have to put the OR within the parenthesis as Mahmoud has provided.

Related

Codeigniter sql binding

How do I use Codeigniter SQL Binding if there are two target dates?
Is how I did it below correct?
public function getInvestmentForBorrowing($id, $Interest, $Currency, $Loantime, $target_date, $Risk_category)
{
$query = '
select CASE WHEN (a.amount_financed - a.amount_invested - a.amount_withdrawn) < a.amount_per_borrower
THEN round((a.amount_financed - a.amount_invested - a.amount_withdrawn), 2)
ELSE round((a.amount_per_borrower) , 2)
END AS investable_amount, a.*,
c.IBAN as Return_IBAN, c.BIC as Return_BIC,
i.average_rate
from investment a
inner join userinfo c
on a.Owner = c.Owner and
c.UPDATE_DT is null
inner join exchange_rates i
on a.Currency = i.currency_id and
? between i.effective_dt and i.expiration_dt
where a.ORIG_ID = ? and
a.Interest <= ? and
a.Currency = ? and
a.status = 2 and
a.Loantime >= ? and
a.Available >= ? and
a.Risk <= ? and
a.UPDATE_DT is null
having investable_amount > 0';
$query = $this->db->query($query, array($target_date, $id ,$Interest, $Currency, $Loantime ,$target_date ,$Risk_category));
$result = $query->result();
return $result;
}
Write now the question marks just represent the array so I added two $target_date to the array but not sure if thats the right way to do it.
It appears to be ok according to the codeigniter documentation but i say that without regard to your original SQL being correct or not.
Just make sure that the number of ? match the number of values you are providing and they are in the right order.
One way to sanity check it, apart from just running it, is to place the following command right after you perform the query:
echo $this->db->last_query();
And providing it known data, you can cheat and just hard code some dummy values for testing, take the generated SQL and throw that into something like phpmyadmin and run it the generated SQL against the Database and see if it works with the expected results.
Just a side note regarding your variable naming style. I see you are mixing cases i.e. things like $target_date (all lower case) and $Risk_category (First letter uppercase). Just be aware that on a linux based system case does matter and mixing like that can cause errors. It's a good idea to decide on one and stick with it.

mySQL $REQUEST defaults

mySQL NOOB question:
Table has a column = AgeGroup. It is populated with the following data options: U40, 40-44, 45-49, 50-54, 55-59, 60+.
I have a form which allows the user to select the 'Gender' and 'AgeGroup' they wish to view. This then uses a "WHERE" clause of "SELECT" SQL query. It uses in the following format:
FROM
#__test1
WHERE
EventName = '2011EoSummer' AND
Gender = {$REQUEST:Gender};
if(isset($_REQUEST['Age'])) AND AgeGroup = {$_REQUEST['Age']}
In the form, there is a option to get all ages via "Overall" but there is no data called "Overall" in the AgeGroup column. Overall should default to ALL age groups, but I don't know how this would read in the SQL query.
Example 1 URL: /&Gender=Men&AgeGroup=U40 => would display data in 'U40' 'Men'
Example 2 URL: /&Gender=Men&Age=Overall => would display ALL Age data
If I'm reading this right, when you have "overall" selected you want to return all the age groups (so as not to limit by any age group)?
If so you need to remove the AgeGroup clause in your SQL statment.
<?PHP
$sql = "SELECT * FROM tbl WHERE Gender = {$_REQUEST['gender']}";
if(isset($_REQUEST['age']))
{
$sql.= " AND AgeGroup = {$_REQUEST['age']}"
}
?>
This will default to overall, so you may want to change the logic appropriately, hope I got what you were after, if not ignore it!
Also as a side note $_REQUEST isn't the best to use, if your using a form as your action collector set it to post and use $_POST instead, if you cant use $_GET to pull your data out of the url instead of request.
Edit: Added in brackets to make it easier to read.

mysql update with regexp

I want to remove something from my table 1) 32) 121) 1000)... the format is number + )
I tried this code.
UPDATE articles SET
title= REPLACE(title,'\d)', '' )
WHERE title regexp "\d)*"
Nothing happened in phpmyadmin, how to write correct? Thanks.
You can't: Mysql doesn't support regex-based replace.
See this SO question for a work-around.
Finally, I use some php to solve this problem with a quickly method.
for ($i=1; $i<=9999; $i++){
$my_regex = $i.')';
mysql_query("UPDATE articles SET title = REPLACE(title,'".$i."', '' ) where title like '%".$i."%'");
}
I have unique requirement where I need to replace inactive owner username. Where username contians INACITVE followed by village id. So I have used concat() funacion inside replace() function to replace dynamically.
update Owner set username = replace(username, concat('_INACTIVE_',village_id) ,'')
where village_id = 3363010;
As an alternative, depending on the size of the table, you could do a workaround with substring function.

zend framework automatically alter queries

My database (mysql) tables use TIMESTAMP columns, and whenever I want them returned in a query, I want them to be queried as "UNIX_TIMESTAMP(columnname)".
How do you easily modify queries in zend framework to achieve this?
For example, the current code is:
select = $this->select();
$select->where('user_id = ?',$user_id);
return $this->fetchAll($select);
This eventually becomes:
select * from tablename where user_id = 42;
I want something that automatically finds the TIMESTAMP column and changes the resulting query to:
select user_id,name,unix_timestamp(created) where user_id = 42;
I know I can use a MySQL view to achieve this, but I'd rather avoid that.
Thanks.
RR
You should be able to specify the fields you want in the select using the $select->from() object.
Zend_Db_Select
You should end up with something like this.
$select = $this->select();
$select->from(
array('t' => 'tablename'),
array('user_id', 'name', 'UNIX_TIMESTAMP(created)')
);
$select->where('user_id = ?',$user_id);
return $this->fetchAll($select);
If you wanted to run an expression that doesn't have parenthese in the function, Use the Zend_Db_Expr() method to escape the query properly.

Propel ORM - Custom where clause

I'm trying to match md5(ID) to an id.
SELECT *
FROM `user` u
WHERE
MD5(`user_id`) = '66f041e16a60928b05a7e228a89c3799'
this is ID = 58
I tried something like this. I know I'm close I just don't know what I'm missing
$criteria = new Criteria();
$criteria->addAnd('md5('.User::USER_ID.')', $_REQUEST['fs'], Criteria::CUSTOM);
$user = UserPeer::doSelectOne($criteria);
Any ideas?
First of all, directly using Criteria objects is deprecated not recommended. You should use Active Query classes.
Using these classes, you will be able to write stuff like this :
UserQuery::create()
->where('md5(User.Password) = ?', $_REQUEST['fs'], PDO::PARAM_STR)
->findOne();
You'll notice that I use the PhpName both of the table and the column in the query.
EDIT : For raw conditions, the parameter type has to be specified. You'll find more information on this issue.
After lenghty T&E process I managed to get it done like this
$c = new Criteria();
$c->add(UserPeer::USER_ID, "md5(user.user_id) = \"".$_REQUEST['fs']."\"", Criteria::CUSTOM); // risk of SQL injection!!
$saved_search = UserPeer::doSelectOne($c);
For some reason PropelORM though that $_REQUEST['fs'] was name of the table rather than the value. \"" solved the problem.