SELECT DISTINCT with so many conditions - php

I am trying to create a Filter feature for my website. I was told to use SELECT DISTICT to accomplish this. Below is what I currently have, it retrieves all the distinct values in column STATE and displays them as check boxes so the user can check those states he wants displayed on a table on the page.
$sql = "SELECT DISTINCT state FROM allproperties";
$result = mysqli_query($con,$sql);
while ($row = mysqli_fetch_array($result)) {
echo "<input type='checkbox' name='state' value='" . $row[0] . "'>" . $row[0] . "<br>";
}
My problem is this Filter feature will have a lot of conditions, not just selecting which States to show, there'd be selections for which county, member age, member contributions etch. When the user clicks DISPLAY button to display the filtered results, I do not know how to build an SQL query for this. If only a few condition I can simply use "SELECT * WHERE (...) AND (....)" but if I use this for a filter feature, there'd be a lot of conditions like:
WHERE (state='CA' OR state='NV' OR state='WA' ..... so on and so fort)
Is there a way to do it like WHERE state=OR('CA','NV','WA') so I don't have so many state=?
Also, does anyone have any sample queries for filter feature? The Filter feature is like when you do a search in a music website for songs based on genre or something. I apologize in advance for the confusing question, I can't find the right question to ask for this.

Yes, you can use IN() :
WHERE state IN('CA','NV','WA'...)
Its not only doing the same effect, it's a lot more efficient then severals ORs , always try to avoid unnecessary OR's .
As mentioned by #Kulvar , you can use implode() to make it work with PHP , something like:
'WHERE state IN(' . implode(',', $states) . ')'

Related

PHP - Getting num_rows of different ID's without writing new statements?

Basically, I'm coding a site that has many different categories and I want to display the amount of rows specific to that ID.
So for example, I have as the query:
$query= "SELECT job_sec FROM jobs WHERE job_sec = ?";
mysqli_num_rows($query);
I need to know how I can count the rows of an ID then echo the rows counted.
I'd like the results to display:
Web Design: 2,001 jobs
Logo Design: 5,120 Jobs
The job_sec column just uses a numerical value, would it be easier to have a text value then count the rows relating to the text value and echo them?
I have a feeling I need to use an array however I need the most efficient method.
Any help would be much appreciated!
Assuming job_sec is the category and I think you are looking for "group by":
$sql= "SELECT job_sec, count(*) AS c FROM jobs GROUP BY job_sec";
$r = mysqli_query($sql);
while ($row = mysqli_fetch_assoc($r)) {
echo $row['job_sec'] . ': ' . $row['c'] . ' Jobs ';
}
(didn't test and not sure if the mysqli syntax is correct)

blank spaces and repetition in dropdown box

My drop down boxes are working fine using multiples of this code which, I admit, is very rudimentary:
$sql = "SELECT Country FROM engravers order by Country";
$result = mysql_query($sql);
echo "<select name\\='Country'>";
echo "<option value='$_POST'>Country</option>";
while ($row = mysql_fetch_array($result)) {
echo "<option value='" . $row['Country'] . "'>" . $row['Country'] . "</option>";
}
echo "</select>";
The only problem is that if I have more than one item in the field I get a response for each item, for instance, in my testing database there are two rows with Australia as the country. My dropdown then puts Australia in twice. Later, when there will be about a hundred Australian entries this will be a problem.
Also if there is a blank field I get a blank line in the drop down box. I don't seem to be able to find a solution to this. Is there a better way to write the drop down code that doesn't do this. Unfortunately, as a novice, I am using the simplest code I can understand but the results look just like that. Any help would be gratefully accepted.
Try this query:
SELECT DISTINCT Country
FROM engravers
WHERE Country <> ''
ORDER BY Country
SELECT DISTINCT will take care of multiples - if there are 100 rows with Country = Australia, it will only select one.
WHERE Country <> '' will exclude any rows that have a blank value for Country. You could also include AND Country IS NOT NULL to exclude NULL values as well.
References:
<> (Not equal operator), SELECT DISTINCT ...

How to call one cell of a database?

I am very new to using PHP so I am asking for some help. I have this code which works fine (I got it online from somewhere).
$data = mysql_query("SELECT * FROM products")
or die(mysql_error());
print "<table border cellpadding=3>";
while($info = mysql_fetch_array( $data ))
{
print "<tr>";
print "<th>title:</th> <td>".$info['title'] . "</td> ";
print "<th>info:</th> <td>".$info['information'] . " </td></tr>";
}
print "</table>";
But what PHP would I use to pull just one cell? For example, I have 9 items in my db with productIDs how could I call just the name or price or description for that particular product?
Thanks in advance.
It sounds like you want a particular row, in which, case you would just changes your query to filter for some specific value that identifies the row. THis might look something like this:
SELECT * FROM products WHERE product_id = ?
Where ? is the known product_id value that you want to receive the full record for.
Also, since you are just learning, I should point out that you should not learn to use mysql_* functions. They are deprecated. Learn mysqli or PDO for interacting with MySQL.
To obtain just one cell try the following:
SELECT CellName FROM TableName Where productId = x
So to get the price you would do:
SELECT price FROM products WHERE productid=x
Where productid equals the specific product you talked about.
if you want to understand a bit more mysql I advise you to go to PhpMyAdmin and try those and think about the result:
SELECT * FROM products;
SELECT title, information AS lol FROM products;
SELECT title, count(*) AS count FROM products;
SELECT * FROM products WHERE title = 'XXXX';
SELECT *, count(*), CHAR_LENGTH(title) FROM products;
SELECT title AS lol FROM products;
you will understand better the query language i thinks.
please read this chapter http://dev.mysql.com/doc/refman/5.0/en/examples.html. it'll really help you.
I just want to say, you can retrieve any columns(s) in any condition column
SELECT column_name(s) FROM products WHERE colmnm_name = ?

Trying to search one table using the value from another table

I am trying to program a lookup tool in PHP with SQL database.
$sql="SELECT
ID,
switch,
vlan,
circuit_id
FROM vlan
WHERE switch
LIKE LOWER('%" . $name . "%') OR vlan='" . $name ."'
ORDER BY vlan";
then further down I have this to put the results into variables:
while($row=mysql_fetch_array($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
What I am wanting to do is take the switch reply and use that to do another query on a different table named router and return that information.
I have been searching for a few days and all of my searches ended up here but didnt seem to quite fit. I apreciate any help you can give.
UPDATE
With some great answers I finally got this to work. Here is how I did it. Thanks for the help.
while($row=mysql_fetch_assoc($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
$sql2 = "SELECT IPAddress FROM router
WHERE switch LIKE '%".$switch."%'
LIMIT 1";
$result2 = mysql_query($sql2);
$row2=mysql_fetch_array($result2);
$IPAddress = $row2['IPAddress'];
Probably real ugly to the more experienced but it works. Thanks again.
It would be highly inefficient to run a secondary lookup query in a loop.
What you want is a simple JOIN between your two tables based on the switch field. What this will do is bring the linked rows in your router table alongside the rows in your vlan table where values in the switch column match up:
$sql = '
SELECT a.id, a.switch, a.vlan, a.circuit_id, b.ipaddress
FROM vlan a
JOIN router b ON a.switch = b.switch
WHERE a.switch LIKE "%' . strtolower($name) . '%" OR vlan = "' . $name . '"
ORDER BY a.vlan';
Then in your same fetch loop, you'll be able to access the linked values from your router table without having to run extra database calls:
while($row=mysql_fetch_array($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
$ipaddress = $row['ipaddress'];
}
How many results do you expect? If there's more than one result, you might need to point which row exactly you want to take. Since it's fetch_array, your $row['switch'] or $switch value is still an array. var_dump it for keys and use the key, i.e.
SELECT `col` FROM `router` WHERE `switch` = '$switch[1]'

Displaying info from MySQL - from 2 different tables... Argh! Noob in trouble

I am trying to pull some stats from a gameserver database, and return them in a table.
I have managed to do the first bit - pulling 10 results, displaying in a table in html, HOWEVER... the next bit has me stumped... I for each player I want to get some info from another table...
Here is what I have so far... excuse the messy code, I am just learning!
// adding ALL info from the first 10 tables 'profile' based on humanity, ascending, to the variable 'profile_info'
$profile_info = mysql_query("SELECT * FROM profile ORDER BY humanity desc LIMIT 10");
while($row = mysql_fetch_array($profile_info))
{
// Below I add the players unique ID into the variable $unique, to be used later for pulling their survival time from the 2nd table, which is called 'survivor'
$unique = $row['unique_id'];
echo "<tr>";
echo "<td class=\"c1\">" . $row['name'] . "</td>";
echo "<td class=\"c2\">" . $row['humanity'] . "</td>";
echo "<td class=\"c3\">" . $row['total_survivor_kills'] . "</td>";
echo "<td class=\"c4\">" . $row['total_bandit_kills'] . "</td>";
echo "<td class=\"c5\">" . $row['total_zombie_kills'] . "</td>";
echo "<td class=\"c6\">" . $unique . "</td>";
//In the line below, I try to get data from the 2nd table (called survivor), checking for the unique_id for the player (extracted from the first table, called 'profile') which is common across both tables and which have a 0 in the field 'is_dead'
$result = mysql_query("SELECT * FROM `survivor` WHERE `unique_id` ='.$unique' AND `is_dead` = 0") or die(mysql_error());
echo $unique;
if (mysql_num_rows($result)) {
$survivors_survival_time = mysql_fetch_assoc($result);
echo "<td class=\"c7\">" . $survivors_survival_time['survival_time'] . "</td>";
}
I hope that, even though the code above is probably rubbish, you can see what I am trying to do?
Most of it works fine, it is just that the part where I try to get the info for a player from the second table, based on their unique_id from their row in the first table, it doesn't work :(
Any ideas, or is the above so bad I should just give up?
I believe you have a typo in your query that pulls info for each individual player here:
mysql_query("SELECT * FROM `survivor` WHERE `unique_id` ='.$unique' AND `is_dead` = 0")
Specifically, the unique_id = '.$unique' part, where there is an extra . in the value field.
Try removing it to get the following:
$result = mysql_query("SELECT * FROM `survivor` WHERE `unique_id`='$unique' AND `is_dead` = 0") or die(mysql_error());
This, of course, is under the assumption that you don't prepend a . to each of your unique_id values in the survivor table.
Side-note (not answer specific):
If you were to update your code to use the MySQLi or PDO libraries opposed to the deprecated mysql_ functions, you would have the ability to use prepared statements. Using these would prevent minor errors like the one noted above as well as provide more-secure code too.
Nest your while loops or read about mysql LEFT JOIN and update your query.
I do not know about MySQL, because I've always used MSSQL, but here's how I would write it in PHP and mssql:
'SELECT * FROM survivor WHERE unique_id="'.$unique.'" AND is_dead = 0'
Try it and let me know ;)
You can combine those queries using a join:
SELECT
*
FROM
profile AS p
LEFT JOIN
survivor AS s ON p.unique_id = s.unique_id
WHERE
s.is_dead = 0
ORDER BY
humanity DESC
LIMIT
10
Then simply loop the results. Using LEFT JOIN gives you all the results from profile and any matches in survivor. If you change that to JOIN (i.e. drop the LEFT) it will give you only rows where a match exists in profile AND survivor.
A couple of suggestions:
Explicitly state which columns you want, i.e. "SELECT name, humanity, survival_time, etc..." instead of SELECT *.
Use a query method that allows you to use prepared statements, such as PDO.
Use single quotes instead of doubles so that you don't have to escape all the doubles in your HTML output. Anyone else who reads your code will thank you for that!

Categories