Say I have the two following tables:
country_table:
---------------------------------
|ID|country_code|country_name |
|01|CA |Canada |
|02|US |United States |
---------------------------------
user_table:
----------------------------------------------
|id|user_id|country_code|email_address |
|01|oswalsh|CA |blah#hotmail.com |
|02|jlong |US |blah2#hotmail.com |
----------------------------------------------
I am creating my user signup/edit account forms, and have a drop down for country. Originally I had simply stored the country_name in the user_table instead of using a country_code, however I have also decided to implement a map script...which is a massive mess of javascript files which make use of the country_code.
Thus I created the country_table so I could match the country_code and the country_name so I could map user interactions...However I am not sure how to go about creating the sql statement for the drop down.
What I have so far:
<?php
include ('../../connect.php');
$account_panel = mysql_query("SELECT * FROM user_table WHERE id=1")
or die(mysql_error());
while($row1 = mysql_fetch_array( $account_panel ))
{
?>
<select name="event_country" id="event_country" required />
<option selected="selected" value="<?php echo $row1['user_country']; ?>"><?php echo $row1['user_country']; ?></option>
<?php
$countries = mysql_query("SELECT * FROM country_table")
or die(mysql_error());
while($row = mysql_fetch_array( $countries ))
{
echo "<option value='". $row['value'] ."'>". $row['name'] ."</option>";
}
echo "</select>";
?>
<?php
}
mysql_close($connection);
?>
So as you should be able to see from above what is happening, is that the list is populated from the country_table, but I am trying to get the selected value from the user table. This does seem to work, but my problem is that the country code is what is stored and being displayed. So say I am grabbing the info for oswalsh...me...the country returned is CA, and I would like it to display Canada.
If I understood you right, you need to familiarize yourself with SQL Joins
To join those two tables and get the country_name along with the user data from the user_table, you'd need an SQL statement like this:
SELECT ut.*, ct.country_name
FROM user_table ut
INNER JOIN country_table ct
ON ut.country_code = ct.country_code
In your case, this would result in the following:
1 oswalsh CA blah#hotmail.com Canada
2 jlong US blah2#hotmail.com United States
Also, you should consider using mysqli_ and stop using mysql_ functions. Here is a discussion on this topic on SA.
Related
I am pretty new to php and sql and am learning as i create a web app so i'm wondering how this would be possible, if at all, or if there are better practices for this sort of task.
just as an example:
Say i have a database with 2 tables
one is author, the other book
author table
-----------
id | author
1 | jones
2 | jane
book table
----------
id | title | author
1 | Learning php | 1 <- i want this to reference the author from author table
2 | Foobar | 1
3 | How to give a proper high five | 2
i have a form that gets the authors name from a query as a select tag and i want to assign the id as the value for author in the book table when i submit the form
$authorQuery = mysqli_query($con, "SELECT * FROM author");
<form id="bookForm" action="books.php" method="POST">
<label for="title">Book Title</label>
<input type="text" name="title">
<label for="author">Author</label>
<select id="author" name="author">
<?php
while($row = mysqli_fetch_array($authorQuery)) {
//display as an array in a drop down list
echo '<option>' . $row['author'] . '</option>';
}
?>
</form>
How would i go about this?
I will make the options values as the authors Ids, change this
echo '<option>' . $row['author'] . '</option>';
to this
echo '<option value="' . $row['id']. '">' . htmlspecialchars($row['author']) . '</option>';
Now, when this form is submitted , at the server you will receive the id of the author in the $_POST['author'] variable, so you can make your update query using the id instead of the name of the author.
$query = "update book set author_id = ? where title = ?";
$stmt = $con->prepare($query);
$stmt->bind_param("is", $_POST['author'], $_POST['title']);
$stmt->execute();
suggestions:
this scheme means that your relationship is 1:m (1 author can write many books, but 1 book is must be written by only 1 author), this is not correct, as many books are written by many authors, so you need to use a third conjunction table to represent the many to many relationship m:m
The search on MySQL is case insensitive by default, however it's better to make a <select> for the books instead of <input> and assign the IDs of the books to the <option>s instead of typing the title (unless you have too much books to fit in a select), so you make sure you avoid any typos in the title of the book when you need to fill the form to assign an author to a book
The easiest way will be to
<?php $stmt = $conn->prepare("SELECT * from book")
$stmt->execute();
foreach($stmt as $row){
$id = $row['author'];
$stmt = $conn->prepare("SELECT * from author WHERE id='$id'")
$stmt->execute();
foreach($stmt as $row){
$name = $row['author'];
?><option value="<?php echo $name;?>"><?php echo $name;?></option>
}
}
The Complex Method is
$stmt = $conn->prepare("SELECT *, book.author AS bookauthor FROM book LEFT JOIN author ON author.id=book.id");
$stmt->execute();
foreach ($stmt as $row) {
?><option value="<?php echo $row['bookauthor'];?>"><?php echo $row['bookauthor'];?></option>
}
I have two tags, the first one is to select the brand and the second one is to select the product.
My question/problem is that I want to tell php to echo inside the second select tag. The echoed option needs to have the same brand_name as the selected option from the first tag.
What I need is that if I choose Adidas as the brand, php would show every product that has the brand_name Adidas.
I have two different database tables, the first one called brand:
brand_id | brand_name
1 | ADIDAS
2 | NIKE
The second one called product:
product_id | brand_name | product_name | product_image | amount | sell | buy
1 | ADIDAS | T-Shirt | none | 50 | 30 | 28
2 | NIKE | Shoes | none | 20 | 130 | 120
Here is my code:
<select>
<option disabled selected>----SELECT----</option>
<?php
require_once 'connections/dbc.php';
$query = "SELECT `brand_name` FROM `brands`";
$response = #mysqli_query($conn, $query);
if (!$response) {
$_SESSION['errortitle'] ='Error loading the brands';
$_SESSION['errormessage'] = 'Something wrong happend while loading the brands.<br/>Please contact The developer';
header("location: error.php");
exit();
} else {
while($row = mysqli_fetch_array($response)){
echo '<option name="brand_name" value='.$row['brand_name'].'>'.$row['brand_name'].'</option>';
}
}
?>
</select>
<select>
<option disabled selected>----SELECT----</option>
<?php
require_once 'connections/dbc.php';
###########HERE WHERE I NEED MY CODE##############
$query = "SELECT `product_name` FROM `product WHERE brand_name = "##### The selected option from the first select tag" ";
$response = #mysqli_query($conn, $query);
if (!$response) {
$_SESSION['errortitle'] = "Error loading the prouducts";
$_SESSION['errormessage'] = 'Something wrong happend while loading the proudcts.<br/>Please contact The developer';
header("location: error.php");
exit();
} else {
while($row = mysqli_fetch_array($response)){
echo '<option name="product_name" value='.$row['product_name'].'>'.$row['product_name'].'</option>';
}
}
?>
</select>
There are two options:
First: Download all contents of 'products' table, and make script that will add items with selected 'brand' attribute to box.
Second: (Recommended) When user selects a brand, make an AJAX query, and get all items with selected brand.
Second one is much better, because you will need to download less data, and page will load faster.
Imagine you have 10^9 products, and 10^7 brands(average 100 products per brand)
Using first solution, you will need to download all 10^9 products, and then use JavaScript(which is not very fast) to select 100 of them.
If you use second solution two things are going to be much better:
1. Download 100 items instead of 10^9.
2. To select items use fast SQL engine instead of slow JavaScript
It is not possible to do it with php, because php is server-side. Server is making page code with php, and then sending it to user. It's impossible to make callback to php without AJAX
The easiest way to do this would be to use a single SELECT with LEFT JOIN, to get all of the columns from both tables at the same time:
SELECT brands.brand_name, products.product_name FROM brands LEFT JOIN products on brands.brand_name = products.brand_name GROUP BY brands.brand_name
And build both of your <select> nodes from that single query. To do this, build your first <select> node from the query, the same as you are doing now, then in the lower part of the code reset the $response with $response->data_seek(0). Then you can build the second <select> as though you had done another query.
It will look something like the following code. There are only two minor changes to your original. Look for some comments in the top section, and some in the bottom section. I don't have an easy mechanism to run PHP, so I can't test it, and it might not run perfectly as it is now. But I think it will give you an idea of what to do.
<select>
<option disabled selected>----SELECT----</option>
<?php
require_once 'connections/dbc.php';
// Notice that the query includes LEFT JOIN, to get the
// columns from both tables in a single query.
$query = "SELECT brands.brand_name, products.product_name
FROM brands left join products on brands.brand_name = products.brand_name"
$response = #mysqli_query($conn, $query);
if (!$response) {
$_SESSION['errortitle'] ='Error loading the brands';
$_SESSION['errormessage'] = 'Something wrong happend while loading the brands.<br/>Please contact The developer';
header("location: error.php");
exit();
} else {
while($row = mysqli_fetch_array($response)){
echo '<option name="brand_name" value='.$row['brand_name'].'>'.$row['brand_name'].'</option>';
}
}
?>
</select>
<select>
<option disabled selected>----SELECT----</option>
<?php
require_once 'connections/dbc.php';
// Here, you don't need another query. You simply reset
// $response, and then fetch as you would from a
// normal query.
$response->data_seek(0);
while($row = mysqli_fetch_array($response)){
echo '<option name="product_name" value='.$row['product_name'].'>'.$row['product_name'].'</option>';
}
?>
</select>
You can simply use Ajax to do this. I'll try to explain step by step.
I assume jQuery is loaded.
Your product table should use brand_id not brand_name.
product_id|brand_name | product_name | product_image | amount | sell | buy
1 |brand_name_1| T-Shirt | none | 50 | 30 | 28
2 |brand_name_2| Shoes | none | 20 | 130 | 120
I hope this will help you.
Step - Create your first and second select box by using name or id attributes. I will be using the name to define them.
<select name="brand_name">
<?php //call brand_name options from your database
//Sample : <option value="brand_name_1">Brand_Name_1</option>?>
</select>
<select name="product_name" disabled >
<?php //dont fill this select box.
//Leave it empty, contents will be created after our ajax call
?>
</select>
Step
Add jQuery script to your page as below.
<script>
$('[name="brand_name"]').change(function(event){
var brand_name = $(this).val();
$.get(
"ajax.php",
{ brand_name: brand_name },
function(data) {
var opts = $.parseJSON(data);
$.each(opts, function(i, d) {
$('[name="product_name"]').append($('<option>', {
value: d.product_name,
text : d.product_name
}));
});
//Enable the product_name select box
$('[name="product_name"]').prop('disabled', false);
//Refresh the product_name select box
$('[name="product_name"]').selectpicker('refresh');
}
);
});
</script>
Step - The ajax.php must look something like below. I have used your php query code here.
<?php
require_once 'connections/dbc.php';
$getBrandName = $_REQUEST['brand_name']; // This is the id of the selected brand name
$query = "SELECT product_name FROM product WHERE brand_id = '$getBrandName' ";
$response = #mysqli_query($conn, $query);
if (!$response) {
$_SESSION['errortitle'] = "Error loading the prouducts";
$_SESSION['errormessage'] = 'Something wrong happend while loading the proudcts.<br/>Please contact The developer';
//Below Header method will not work cause headers are already been set. You will not be able to redirect page. So just delete it. instead you can return an error by using the json.
header("location: error.php");
exit();
} else {
while($row = mysqli_fetch_array($response)){
$prodyctsArray[]['name'] = $row['product_name'];
}
echo json_encode($brandName);
}
?>
For more information I suggest you to visit references below:
jQuery.ajax()
jQuery.get()
Introducing JSON
I have two tables and i want to echo the total call count once each user logins:
Login
Firstname | Lastname | Login ID
------------------------------
Tyler | Durden | 3
Call Count
Name | Call Count | Open | GrandTotal
------------------------------
Tyler Durden| 100 | 33 | 133
i tried:
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name=".$_SESSION['firstname']. ' ' .$_SESSION['lastname']." ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
But its not working, i think i have to join the the two tables to get it to work. What do you think?
Assuming your Call Count table is actually called csvdata, you'll want to format your SQL request string a bit by adding single quotes around the WHERE name = part.
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name='".$_SESSION['firstname']. ' ' .$_SESSION['lastname']."' ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Call Count'].' Call Count';
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
Good practice would require that you use primary keys to facilitate joins between tables and make sure two users with the same name can be differenciated.
In that case you may want to consider replacing the Name column in your Call Count table for your loginID. This way you could get your name from the Login table (as shown below). Also, as bad as it is to have duplicated data like your user's name in both tables, you do not need your GrandTotal column since you can easily get the sum of CallCount and Open to get the exact same number. In the end, your query should look more like this (assuming your tables are called Login and CallCount).
<?php
$result = mysqli_query($mysqli, "SELECT l.FirstName, l.LastName, cc.CallCount, cc.Open, (cc.CallCount + cc.Open) AS GrandTotal FROM Login AS l JOIN CallCount AS cc ON l.LoginID = cc.LoginID WHERE l.FirstName LIKE \"".$_SESSION['firstname']."\" AND l.LastName LIKE \"".$_SESSION['lastname']."\"");
// ...
?>
I would like to show the count value for the mysql result in html table.
For an example "district Name1" is the name of "district name" and "count-value1" shows the total post office count in "district name1".
My output must be like this,
------------------------
District | Post Offices
------------------------
Name1 | Count-Value1
Name2 | Count-Value2
Name3 | Count-Value3
Name4 | Count-Value4
... | ...
------------------------
Anyone can please help me to fix this..
This is my PHP code,
<?php
include('config.php');
$data_content= "";
$qry = "SELECT DISTINCT district_N,state_N FROM pincode_data WHERE state_N ='" . mysql_real_escape_string($_GET['st'])."' ORDER BY district_N ASC";
$result = mysql_query($qry);
while($row = mysql_fetch_array($result))
{
$dist_Value = $row['district_N'];
$state_Value = $row['state_N'];
$data_content.= "<tr><td><a href='pincity.php?dist=".$row['district_N']."'> ".$row['district_N']."</a></td><td>Count Value to be Displayed Here</td></tr>";
}
mysql_close();
?>
This is my HTML code,
<html>
<head>
</head>
<body>
<h1>Pincodes in <?php echo $state_Value; ?></h1>
<div>
<table>
<tr><td>District</td><td>Post Offices</td></tr>
<?php echo $data_content; ?>
</table>
</div>
</body>
</html>
SQL has syntax for counting elements of a group. If you want to count all occurrences of each value for X in a table, the general form is select X, count(X) from <table> GROUP BY X. This will group all equal values of X together, and give you a total count of them. For your particular case, try this:
$qry = "SELECT district_N,state_N, COUNT(district_N) cnt
FROM pincode_data WHERE state_N ='" . mysql_real_escape_string($_GET['st'])."'
GROUP BY district_N ORDER BY district_N ASC";
Also, it is good to see that you are escaping the parameters - but mysql_* is deprecated and will be removed in future versions of PHP. You are best off to use either mysqli_* or PDO. In either case, you should also look into prepared statements and parameter binding. It's good for your health.
Basically I have a database with 66 bible books; some from old testament some from new. The bname value is the NAME of the book, while bsect has a value of O or N(new or old), how can I make my dropdown box dynamically display a book into an old or new optgroup based on whether its' bsect is O or N? My teacher said I have to make some array, but i have no idea how to do it. Any thoughts?
My database sample:
+-----------+-------+
| bname | bsect |
+-----------+-------+
| Genesis | O |
| Exodus | O |
| Leviticus | O |
+-----------+-------+
I don't want to have to rely on manually setting opgroups based on the NUMBER OF THE ENTRY, I want it to be dynamic based on value of bsect.
Right now I just have the following query with a select dropdown which puts the book into old or new based on its record number, but It will break if more books were to be added
$query = $mysqli->query("select distinct bname as Name from kjv");
?>
<select name="book">
<?php
$i=1;
while($option = $query->fetch_object()){
if($i==1) echo "<optgroup label='Old Testament'>";
else if($i==40) echo "<optgroup label='New Testament'>";
echo "<option value='$i'>".$option->Name."</option>";
$i++;
}
?>
Simply order by bsect and display different optgroups dynamically
<?php
$query = $mysqli->query("SELECT DISTINCT bsect, bname AS Name FROM kjv ORDER BY bsect");
?>
<select name="book">
<?php
$i = 1;
$bsect = "";
while($option = $query->fetch_object()){
if($bsect != $option->bsect) {
$bsect = $option->bsect;
echo "<optgroup label='{$bsect}'>";
}
else if($i==40) echo "<optgroup label='New Testament'>";
echo "<option value='$i'>".$option->Name."</option>";
$i++;
}
?>
Of course, then your books may be out of order. So what you would want to do is add a book-order column (border) that stores a number defining how to order the books in a given group, e.g.
ALTER TABLE kjy
ADD COLUMN border INT U?NSIGNED NOT NULL DEFAULT 0;
Then you can update the data to have the proper book order and do a query like this:
SELECT DISTINCT bsect, bname AS Name FROM kjv ORDER BY bsect, border;
Of course, this being the Bible, you aren't going to be adding books, so you can probably just define a static Book ID that defines the ordinality of each book. Then you could just sort by ID and know that "Old" and "New" books are coming out in the right order.
ALTER TABLE kjy
ADD COLUMN id INT UNSIGNED NOT NULL PRIMARY KEY BEFORE (bname);
This is how you can create 2 arrays in php,
$query = $mysqli->query("select distinct bname,bsect from kjv");
while($option = $query->fetch_object()){
if ($option->bsect == 'O'){
$books_old[] = $option->bname;
} elseif ($option->bsect == 'N'){
$books_new[] = $option->bname;
} else {
# Error collection - bsect not 'O' or 'N'
}
}
now you have 2 arrays which are lists of books; $books_old and $books_new.
I'd use the name as the value rather than an arbitrary index;
echo "<optgroup label='Old Testament'>";
foreach($books_old as $this_book){
echo "<option value=\"$this_book\">$this_book</option>";
}
echo "<optgroup label='New Testament'>";
foreach($books_new as $this_book){
echo "<option value=\"$this_book\">$this_book</option>";
}