Query Custom WordPress/buddyPress Table (PHP/MySQL) - php

I have been looking around and trying different things for a while and no luck.
Scenario: I have WordPress/BuddyPress and I added in a few new tables to the database through phpMyAdmin. I cannot run a successful query to them, yet I can to all the original tables. I have tried many things, this is my most recent try, still not working:
$b1_exc = $wpdb->get_results( $wpdb->prepare("SELECT * FROM memberbadge
WHERE 1") );
I would really appreciate a solution to add custom tables and be able to query them.
Thank you in advance!

As of 3.5, wpdb::prepare() enforces a minimum of 2 arguments.
This is the correct syntax for wpdb::prepare(), use this.
$result = $wpdb->get_results( $wpdb->prepare("SELECT * FROM memberbadge WHERE %d", 1) );

It's probably a prefix problem.
Try:
$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}memberbadge") );
If you really need a WHERE clause and the variable comes from user input, then use prepare.

Related

Use multiple conditions in SQL WHERE clause using OR

I've got the following SQL statement in my PHP code:
$strSQL = "SELECT * FROM coaches WHERE pastors='1' OR all_categories='1' ORDER BY l_name";
but the WHERE portion after the OR is ignored. Is my code correct? Is there a better way to code it?
Thanks for the suggestions. Even though people said it should work, for some reason it wasn't. The easiest solution was to simply set every true/false to 1 for those individuals who want to be in all categories instead of trying to fight against the OR which looks correct but won't work.
I am trying to get it to select database entries if there is a 1 in a particular category, in this case "pastors", or if there is a 1 in the "all_categories" category.
From the looks of it, your code does just that.
You're just forgetting ASC or DESC at the end of it.
It should look more like this:
$strSQL = "SELECT * FROM coaches WHERE pastors='1' OR all_categories='1' ORDER BY l_name ASC";

What's the best way to apply the same rule in multiple queries?

My application has a dashboard screen which has many charts showing metrics and results of user activity, sales performance, etc.
These results can be filtered by date, user and many other options. Supposing I've got one query for each chart, what's the best way to apply the same filtering rule in these multiple queries? Whats the best way to replicate the same "where" clause (the same filtering rule) accross many queries?
As example,
SELECT * FROM users WHERE date = '2014-10-03';
SELECT * FROM products WHERE date = '2014-10-03';
Both queries have same rules.
Some suggested to set a variable with this rule and concatenate it to other queries. Something like:
$where = "WHERE date = '2014-10-03'";
$query = "SELECT * FROM users ". $where;
...
$query = "SELECT * FROM products ". $where;
...
But I can't see this as a good pratice.
If it is similar to issue I had in past I guess you need these restricted by many often repetitive WHERE conditions. User, department permission, time, etc.
What worked in my case was making these into string variables and reusing them across queries that produce charts and graphs. Of course, do not insert user data into your dynamic queries. Hope it helps.
Would it not be a better idea to only keep the value dynamic in case tables do not share the same column name for date.
$date = '2014-10-03';
$query = "SELECT * FROM users WHERE `date_added` = $date";
$query = "SELECT * FROM products WHERE `date_purchased` = $date";
Note: use appropriate validation and security checks for using user input data in sql.
I think you should look into using Prepared Statements. Similar to bind variables in Oracle.
The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters
Good explanation here: http://docs.php.net/pdo.prepared-statements
Prevents SQL injection attacks as well

Can I just SELECT one column in MYSQL instead of all, to make it faster?

I want to do something like this:
$query=mysql_query("SELECT userid FROM users WHERE username='$username'");
$the_user_id= .....
Because all I want is the user ID that corresponds to the username.
The usual way would be that:
$query=mysql_query("SELECT * FROM users WHERE username='$username'");
while ($row = mysql_fetch_assoc($query))
$the_user_id= $row['userid'];
But is there something more efficient that this?
Thanks a lot, regards
You've hit the nail right on the head: what you want to do is SELECT userid FROM users WHERE username='$username'. Try it - it'll work :)
SELECT * is almost always a bad idea; it's much better to specify the names of the columns you want MySQL to return. Of course, you'll stil need to use mysql_fetch_assoc or something similar to actually get the data into a PHP variable, but at least this saves MySQL the overhead of sending all these columns you won't be using anyway.
As an aside, you may want to use the newer mysqli library or PDO instead. These are also much more efficient than the old mysql library, which is being deprecated.
Not only can you, but you should. Unfortunately too many young developers get in the habit of selecting far too much data. Once you run your query, you don't need to do a while loop since you only have one record coming back. Instead, just use the following:
$sql = sprintf( "SELECT userid FROM users WHERE username = '%s'", $username );
$result = mysql_query( $sql ) or die( mysql_error() );
$data = mysql_result( $result, 0 );
if ( $data ) echo $data; // first userid returned
The second parameter of mysql_result() is the row index you would like to retrieve. 0 is first.
The "usual" way is to only select the columns that you need.
Any column that is part of the select and is not needed will slow down the retrieval. Partly because of network traffic and partly because the database engine can apply certain optimizations if only some columns are selected.
And select * is usually frowned upon in production code.
Your query is correct:
$query = mysql_query("SELECT userid FROM users WHERE username='$username'");
This will work if done correctly. Note that $username must be correctly escaped with mysql_real_escape_string. I'd recommend looking at parameterized queries to reduce the risk of introducing an SQL injection invulnerability.
One other thing you can change is to use mysql_result instead of your loop:
$the_user_id = mysql_result($result, 0);
This assumes that know you'll get only one row.
Yes, that's a great optimization practice!
Also, if you want to go a step further and make it super-optimized, try adding a LIMIT, like this: $query=mysql_query("SELECT userid FROM users WHERE username='$username' LIMIT 1");
This, of course, assumes you expect only one userid to be returned and will make the database engine stop once it finds it.
But, the most important thing: ALWAYS ESCAPE/SANITIZE YOUR INPUT DATA! (can't stress this well enough)
You can do this with a single line of code
echo array_values(mysqli_fetch_array($mysqli->query("SELECT name FROM user WHERE id='$userid'")))[0];
You must connect to the database as shown below before using this
$mysqli = new mysqli('HOST', 'USERNAME', 'PASSWORD', 'DATABASE');
Credits to #samuel t thomas

What's wrong with this mySQL IF Statement?

I'm trying to do this IF statement in a mySQL query which I learnt from a YouTube video. I'm not too sure what's going wrong. I do get the following mysql error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'IF(Cuisine != 'Cuisine', WHERE Cuisine='Cuisine') AS ORDER BY
restaurantID' at line 2
Ok, sorry about the lack of detail. Let me explain this a little more.
On my page, I have a HTML form which has 3 drop-downs which act as 'filters'. The default option for one of these 'filters' is Cuisine, which acts as a title, and if it hasn't been changed it means that the user does not want to use the Cuisine as a filter for their search. However if it has changed to say 'Western', then obviously the user wants to use it.
Now, the above problem is quite simple to solve because there is only one filter at a time in place in the above scenario. However, when there are multiple filters being used at once, this is where it gets complicated for me and I don't know how to address this problem.
My solution was to go and search Google for some sort of IF statement in mySQL. I came across this video (which is probably quite good, however since I was very rushed at the time, probably misinterpreted it). Here is the video: http://www.youtube.com/watch?v=3xK5KKQx-J0
I figured that if I could use the condition and try it for the cuisine, I could research and modify it and work on it some more to get it to completely get the filter system to work.
In the code below, my objective is to check what a PHP variable is = to in SQL, and if it's = to 'Cuisine' then I don't want to execute the 'WHERE Cuisine = $cuisine' part of the query. $cuisine is a variable which is taken from a simple HTML/AJAX form dropdown menu using the 'POST' method.
<?php
$result = mysql_query("SELECT * FROM restaurants
IF($cuisine != 'Cuisine', WHERE Cuisine='$cuisine')
ORDER BY restaurantID
")
or die(mysql_error());
?>
P.S I'm not sure if this is the right approach to solving my problem, however I have now described my train of thought and my problem to you above.
I understand your frustration when I left no detail, and once again I apologise, for wasting your time with a poorly written question I will remember to ensure my future questions/answers are more detailed.
I would move the conditional from the SQL query to PHP where the correct query would be built.
if( $cuisine == 'Cuisine' ) ) {
$conditions = '1'; // "WHERE 1" matches every record
}
else {
$conditions = "Cuisine='$cuisine'";
}
$result = mysql_query( "SELECT * FROM restaurants
WHERE $conditions
ORDER BY restaurantID
") or die(mysql_error());
The above assumes that $cuisine is correctly sanitized and escaped.
What are you trying to do? If you want to select all rows where the Cuisine column is not 'Cuisine', use the WHERE clause:
SELECT * FROM restaurants
WHERE Cuisine != 'Cuisine'
ORDER BY restaurantID
Did not fully understand your question, but if you want to select all restaurants by given cuisine and order them by restaurant ID then you can use:
$result = mysql_query("SELECT * FROM restaurants WHERE Cuisine = '$cuisine' ORDER BY restaurantID")
I see multiple problems, which can only be answered if you provide more information. As of now the error in SQL syntax is ,
The syntax of IF condition is
IF(<condition>, <value if true>, <value if false>)
which is troubling you (you have only two parameters for you IF).

which is better single query or multiple query?

I do have 8 tables. when a query fires from search page data from all these 8 tables is pulled out and displayed on the result page. What I want to know is which is the best optimized query method for this process??
what I do now is :
$result = mysql_query("SELECT * FROM TG_dat,TG_dat1,TG_dat2,TG_dat3 WHERE
TG_dat.web = TG_dat1.web AND TG_dat.web = TG_dat2.web AND TG_dat.web =
TG_dat3.web AND TG_dat.web='".$uri."'")or die(mysql_error());
or do i need to use this??
$result = mysql_query("SELECT * FROM TG_dat WHERE web='$uri'")or die(mysql_error());
$result = mysql_query("SELECT * FROM TG_dat1 WHERE web='$uri'")or die(mysql_error());
$result = mysql_query("SELECT * FROM TG_dat2 WHERE web='$uri'")or die(mysql_error());
$result = mysql_query("SELECT * FROM TG_dat3 WHERE web='$uri'")or die(mysql_error());
Your existing query is perfect - always try to use as few queries as possible.
Less calls to the database is generally better, so you can use the first one.
However, rather than putting all of your tables directly into your FROM clause, it's generally considered good practice to use a join on related tables (which it appears these tables are).
For example:
"SELECT *
FROM TG_dat
LEFT JOIN TG_dat2 USING(web)
LEFT JOIN TG_dat3 USING(web)
WHERE TG_dat.web = '$uri'"
Don't worry so much about the two variations in query you've given - they'll perform more or less the same, but if performance is the issue then the first would be my choice - the single query involves a single round-trip to the server and it's easier to handle the results on the client. It's better to concern yourself with the SELECT *, SELECT <the fields you need> would make more sense - you don't need to have the web field returned multiple times in the results.
your existing query is good. The point is to limit querying db server for better effieciency

Categories