Best method to rewrite complex SQL statement? - php

I have the following SQL statement:
mysql_query("SELECT * FROM `friends` WHERE friend1='$username' OR friend2='$username' AND confirmed='1'");
What I'm trying to accomplish is delete from the table select data from the table friends where one of the two fields is equal to your username, and the confirmed field has to equal 1. This doesn't seem to be working though. What's the best way to rewrite it?

Try this with your friend clauses in parenthesis:
SELECT * FROM friends
WHERE (friend1='$username' OR friend2='$username')
AND confirmed='1'
This will ensure that one of your friend conditions is met. No matter which one matches, it'll also check the confirmed bit. If neither friend condition matches, the row isn't part of the resultset.

Maybe your where clause is not evaluating the conditions in the way you expect?
Try:
mysql_query("SELECT * FROM `friends` WHERE (friend1='$username' OR friend2='$username') AND confirmed='1'");

The following link shows operator precedence in mysql, as you can see AND is evaluated before OR , hence your problem.
http://dev.mysql.com/doc/refman/4.1/en/operator-precedence.html

Related

How to use SUBSTRING() in mysql WHERE query in php

I have a string in a database field (called term6eyfs) that is made up of numbers -> 555555.
I want to count how many of them have a particular number in a particular position.
I have tried the following code, but I'm met with a Boolean given... error
$pos=2;
$analyse_ot="SELECT COUNT(*) AS ot_count FROM base, users
WHERE base.base_id=$base
AND
users.base_id=$base
AND
users.SUBSTRING(term6eyfs,$pos,1)='4'";
$result_ot=mysqli_query($con,$analyse_ot);
$row_ot = mysqli_fetch_assoc($result_ot);//this is where I get the error
$total_ot= $row_ot['ot_count'];
$otper=($total_ot/$total)*100;
I'm guessing that they way I have constructed my query (particularly the final line) isn't correct, but why?
Based on the additional details you gave in the comment I'd say that is what you are looking for:
SELECT COUNT(*) AS ot_count
FROM base, users
WHERE base.base_id=$base
AND users.base_id=$base
AND SUBSTRING(users.term6eyfs,$pos,1)='4'";
(this assumes that "term6eyfs" is the name of a column in the users table)
The context of this query is unclear. But in general it does make sense to use "parameter binding" to inject php variable values into a query string. You want to read about that, it enhances security and robustness.
Also reconsider if you really want to use the , operator to join those two tables. That operator is extremely slow, usually a LEFT JOIN delivery a much better performance.
Change users.substring() to substring
$analyse_ot="SELECT COUNT(*) AS ot_count FROM base, users
WHERE base.base_id=$base
AND
users.base_id=$base
AND
SUBSTRING(term6eyfs,$pos,1)='4'";

sql statement syntax for search

I would like to write an sql statement for search. Here is sample database structure.
For eg, I want to display all records with topic '13'. How can i write sql query for searching 13 from the above structure? Any suggestions?
Can i able to use WHERE Topic LIKE '%13%'? Anything wrong with this?
Try this one:
SELECT * FROM `TABLE_NAME` WHERE `Topic` LIKE "%13%";
It's better and faster to save it in a third table of many-to-many relationship.
If you want to save as per your example (single table), try to save data as eg ",10,13,15,"
always have coma before and after, thus the following sql will exclude 213 and 132 etc
select * from table_name where Topic like '%,13,%'
select * from table where find_in_set("13",topic);
or if topic is not used as a set, you could do ...
select * from table where concat(",",topic) like "%,13,%";
The 2nd isn't real elegant but I've had to do that a couple times.
Because the data isn't really normalized, I used concat to add a comma to the topic field so I could make sure the "like" comparison would pass with a comma before and after the value. I suppose we would also have to remove any unwanted spaces as well for this example, so ultimately it would end up like:
select * from TABLE where concat(",",replace(topic," ","")) like "%,13,%";
Ultimately, we have to know what to expect in the topic column to come up with a query that would always work. In the past, I've had situations where I would add values to a string field (i.e. topic) with a delimiter before and after each value like:
(1)(2)(3)(14)(15)(255)(283)
If you did something like this for the topic field, the query is simple ...
select * from table where topic like "%(13)%";

postgresql: how to SELECT entries that satisfy a condition

I am trying to select the entries that have the same text in the "email" column of my postgreSQL table. I am completly new to database and this is the first database I ever created, so sorry if it's a silly question. My database has 3 columns: key, user_mails and json_adress.
I tried
$existent= "SELECT * FROM
(SELECT public.account_recover_users.* AS keys,emails,jsons
FROM public.account_recover_users)
WHERE emails='$email'";
but I guess I am mistaking somewhere.
Please help, I am trying to learn and I got a bit stuck.
The reason you got the error ERROR: subquery in FROM must have an alias Hint: For example, FROM (SELECT ...) [AS] foo is because you have to give an alias (nickname) to any subquery you use. So, just do what the error message hint tells you to do:
"SELECT *
FROM (
SELECT public.account_recover_users.* AS keys, emails, jsons
FROM public.account_recover_users
) as subq
WHERE emails='$email'"
But you don't need a subquery at all. This could be simplified to just:
"SELECT * FROM account_recover_users WHERE user_mails='$email'"
If you want to rename (i.e. give an alias to) your columns upon selection, I wouldn't use a subquery. Try:
"SELECT key as keys, user_mails as emails, json_adress as jsons
FROM account_recover_users
WHERE emails='$email'"
I don't really recommend this, though. If you're just going to give an alias to every column, why not rename the columns in the database?
I am writing another answer, because the currently accepted answer is wrong in several respects. Neither of the two presented queries can work, even though the OP incorrectly accepted the answer.
The original query couldn't work for several reasons:
As was mentioned (and the error message clearly states): a subquery requires an alias.
As was also mentioned, a subquery is just pointless for the simple task.
This construct is nonsense: public.account_recover_users.* AS keys You can't apply an alias after expanding * to the list of columns. Postgres just ignores it. It might throw an exception in future releases.
According to your description, existing columns are named key, user_mails and json_adress (sic!). emails or jsons are just invalid references.
Your absolutely basic query should be:
"SELECT * FROM public.account_recover_users WHERE emails = '$email'"
You can rename columns in the query by appling column aliases, but your WHERE clause cannot refer to output columns (aliases), it has to refer to input columns:
"SELECT key, user_mails AS email, json_adress AS jsons
FROM public.account_recover_users
WHERE user_mails = '$email'"
Detailed explanation in this related answer:
How to re-use result for SELECT, WHERE and ORDER BY clauses?
Because you're referencing public.account_recover_users in a derived table (in brackets), you need to give the derived table an alias which can be almost anything.
$existent= "SELECT * FROM
(SELECT public.account_recover_users.* AS keys,emails,jsons
FROM public.account_recover_users) as aru
WHERE emails='$email'";
In your case though I don't think you need a derived table at all. You could just write.
$existent = "SELECT key as keys, user_mail as emails, json_address as jsons
FROM public.account_recover_users
WHERE emails='$email'";
You don't need the subquery... (Alias it if you actually need one).
Nor do you need public, since it's in your search path by default.
Nor do you need the fields here, since you're selecting them all.
SELECT * FROM account_recover_users WHERE user_mails='$email'
Oh, and don't forget to escape $email... Look into PDO::prepare().

How to check data for duplication in database?

I have 3 fields of topic name in 3 different languages. When entering new topic I'm using JavaScript to show on the page if that topic exists already in the database by using select and like clause statement. The problem is it finds any duplication if the topic name entered exactly the same, but not if only some words are the same.
How do I check for duplication on topic that checks the words for similarity and not the whole topic?
SQL Server provides Full Text Search feature. You may try for this instead of your like clause.
ATaylor pretty much spells it out for you. To exclude the specific common keywords, I would recommend using an "EXCEPT SELECT WHERE LIKE" statement at the end of your statement.
SELECT DISTINCT(field) AS var1, COUNT(field) AS var2 FROM table GROUP BY field HAVING var2 > 1;
This would show up any field that exist twice or more in your current database
Full Text Search, you can have choice on you relevancy score. write a query to get the most relevant results.
SELECT MATCH('content') AGAINST ('keyword1
keyword2') as relevancy_score FROM topic WHERE MATCH
('Content') AGAINST('+keyword1 +keyword2' IN
BOOLEAN MODE) HAVING relevancy_score > 0.2 ORDER
BY relevancy_score DESC.
you may refer to this link.
http://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html

MySQL Query problem in CodeIgniter

So I'm using the following:
$r = new Record();
$r->select('ip, count(*) as ipcount');
$r->group_by('ip');
$r->order_by('ipcount', 'desc');
$r->limit(5);
$r->get();
foreach($r->all as $record)
{
echo($record->ip." ");
echo($record->ipcount." <br />");
}
Standard:
SELECT `ip`, count(*) as ipcount FROM (`soapi`) GROUP BY `ip` ORDER BY `ipcount` desc LIMIT 5;
And I only get the last (fifth) record echo'ed out and no ipcount echoed.
Is there a different way to go around this? I'm working on learning DataMapper (hence the questions) and need to figure some of this out. I haven't quite wrapped my head around the whole ORM thing.
Is there a way to set the count(*) as ipcount without the funny select() statement? I don't think it's triggering for some reason. This could also be a bug in DataMapper, but I'm less certain of that.
Also I found that even if I use the $r->query() method it doesn't return anything except the last entry if I use something like SELECTipFROMsoapiWHERE 1;. It will however return everything (like it should) if I say SELECT * FROM soapi WHERE 1;. If it doesn't have the * it only returns the last line.
Just verified with the new query, anything except selecting all columns (*) only returns the last record. Any help with this would be great. You can craft a statement like select *, count(*) as ipcount but then you still don't have access to it via $record->ipcount.
For your case, once you use COUNT() function in MySQL, it will only return 1 value. Hence you ip result data would not display out.
I suggest you just split this 2 queries.
1. for COUNT(*)
2. for ip
Hope this help.

Categories