Displaying alternate column when using foreign keys - php

I have an issue regarding PHP, MySql and foreign keys. I understand foreign keys and have a relationship between two tables in place as described:
Let's say I have 2 tables: 'vehicles' and 'manufacturers'.
Each row in the 'vehicles' table includes a manufacturerId column which is a foreign key relating to the 'manufacturers' table. This is set up nicely, in PhpMyAdmin when I insert a new row into the 'vehicles' table the manufacturerId column has a drop-down menu with the manufacturerId's listed as options. Very nice.
BUT: In my application, of course, I don't want the user to have to know (or have to guess) what the correct number for 'Ford' or 'BMW' is when they add a new vehicle, I want them to be able to choose the manufacturer by name.
But how does the application know the manufacturer names based on the manufacturerId? How does the application know there is a relationship between the 2 tables? Am I supposed to hard-code the relationship in the application? Am I supposed to modify all my queries to have a JOIN between the 2 tables? Or hard-code a query to get a list of manufacturers every time I want to display a drop-down of manufacturers?
Is there a way for the application to know about relationships between tables and be able to display data from a text column instead of the int column used as the ID?

Assuming your 2 table are structured like this:
VEHICLES
id
manufacturerId
vehicleName
MANUFACTURERS
id
manufacturerName
You would create your vehicle manufacturer select menu for users by querying the database like this:
// query the database
$q = 'SELECT id, manufacturerName FROM manufacturers';
$r = mysqli_query($link, $q);
// display a select menu using id and manufacturerName
echo '<select name="manufacturer">';
while($row = mysqli_fetch_assoc($r)) {
echo '<option value="'.$row['id'].'">'.$row['manufacturerName'].'</option>';
}
echo '</select>';
To use the post data from that menu to add a vehicle & manufacturer id to your vehicles table:
$q = "INSERT INTO vehicles (manufacturerId, vehicleName) VALUES ({$_POST['manufacturer']}, '{$_POST['vehicleName']}')";
mysqli_query($link, $q);
Finally, if you wish to select the vehicle name and manufacturer in the same query, you would join the tables like this:
// Select vehicle name and manufacturer for vehicle with id of 1
$q = "SELECT v.vehicleName, m.manufacturerName, v.id AS vehicleId, m.id AS manufacturerId
FROM vehicles AS v, manufacturers AS m
WHERE v.manufacturerID = m.id
AND v.id = 1";
mysqli_query($link, $q);
I think that should answer all your questions in one way or another!

Related

How to connect two MySQL tables

I have in my MySqli Database a table called "products".
Products TABLE
product_id | INT primary KEY
product_name | VARCHAR(50)
product_price | float
From PHP i enter rows in the table products like this way:
mysqli_query($con,"INSERT INTO products (product_id,product_name,product_price) VALUES
('$product_id','$product_name','$price')");
So far all work perfectly. Now i want to have a second table called "category", this table will include all the possible categories that a product can have
The Category table must have a category_id and a category_name as columns
Category TABLE
category_id | INT primary KEY
category_name | VARCHAR(50)
I'm trying to figured out a way to connect a product with the category in my PHP file
for example:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
//...
//.. pick the category that the product belong
$category_Selected= .....;
}?>
..... And make the connection (with INSERT? or something) between product and category
Ι want to be able when i'm doing a search at the product table, (for a product X) to show also and the category that it belongs (so far i can show the Product_id, product_name and product_price)
Thank you
You want to join your Tables.
Take a look here:
Join Tables - w3schools
MySQL Join Tables Syntax
If a product can be only in one category then you can add a category_id in your Products table.
I would suggest a third table the:
Product_category
id | PK
product_id | Foreign key to Products.id
category_id| Foreign key to Categories.id
Now every time you insert a product you need to get also the id of your category and do an insert statement to Product_category table.
To retrieve your data you could do something like this:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
$products=mysqli_query($con, "SELECT * FROM `Products` WHERE id IN
(SELECT product_id from Product_category WHERE category_id= ".(int)$row['category_id'] . ")");
while ($product = mysqli_fetch_assoc($products)) {
echo $product["product_name"] . ", " . $product["product_price"];
}
}
The above statement is as example, you could use JOIN and prepared statements.
If you choose to alter the product table and add the category_id there, then
the example code would be this:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
$products=mysqli_query($con, "SELECT * FROM `Products` WHERE category_id = " . (int) $row["category_id"]);
while ($product = mysqli_fetch_assoc($products)) {
echo $product["product_name"] . ", " . $product["product_price"];
}
}
As it is, your database does not allow you to represent the relationshup between categories and products. You would need to alter your design.
I can imagine that one product belongs to a category, and that one category can have several products.
If so, I would recommend creating a categories table to store the categories, with (at least) columns category_id and category_name.
CREATE TABLE categories (
category_id INT PRIMARY KEY AUTO_INCREMENT,
category_name VARCHAR(100)
);
In the product table, you want to add a column in the products table that stores a reference to the id of the corresponding category :
ALTER TABLE products ADD
COLUMN category_id INT
FOREIGN KEY (category_fk) REFERENCES categories(id) ON DELETE CASCADE;
With this modified database design, when you insert into products, you pass the reference of the category (one could expect that the user of your application will select it from some kind of drop down list when creating the product) :
INSERT INTO products (product_id, product_name, product_price, category_id)
VALUES ( :product_id, :product_name, :price, :category_id );
And when you want to display a product along with its category name, you can use a simple JOIN :
SELECT p.*, c.category_name
FROM products p
INNER JOIN categories c ON c.category_id = p.category_id
WHERE p.produt_id = :product_id
PS : never pass POSTed values to your SQL queries like this : this exposes you to SQL injection (and also makes your queries less readable and efficient). I changed the queries to use named parameters.

using union on two tables but renaming the field

I have two tables that have an id field with the same name. I didn't think I'd ever need to mix the two but there's one page where I need to. I can't join the tables because they both have completely separate data and no fields in common.
I can union them but the ID field is the same name and many identical numbers (which do not relate). I can't change the name in the tables but I need the field names to be different when put into a variable (using PHP).
I tried something like this:
SELECT date, id as id1
FROM football
UNION
SELECT date, id as id2
FROM basketball
ORDER BY date
But that just gives me one field (id1). I need the result to be in such a way that I can do this:
foreach ($rows as $row) {
if (!empty($row['id1'])) {
$id = $row['id1'];
$sport = "football";
} else {
$id = $row['id2'];
$sport = "basketball";
}
echo "my number is $id and I play $sport";
}
From MySQL Union Syntax
The column names from the first SELECT statement are used as the
column names for the results returned.
You could assign sport in your query:
SELECT date, id, 'football' as sport
FROM football
UNION
SELECT date, id, 'basketball' as sport
FROM basketball
ORDER BY date

Search data from multiple table

I have 2 table
Table-1 - user
user(ID.Name,Class)
Table-2 - Category
Category(ID,user_id,cat_id)
if user input a data from text field the how to search data from both table
Just query both tables and use the 'OR' operator for the columns you want to search in
SELECT * from user, category WHERE user.id=[text field] or category.user_id=[text field] or category.cat_id=[text field]
PHP Example: (assuming you are using MySQL database - you also need mysqli enabled in your php.ini file)
$mysqli = mysqli_connect(HOSTNAME, USERNAME, PASSWORD, DATABASE);
if (mysqli_connect_errno($mysqli)) {throw new exception("Failed to connect to MySQL: " . mysqli_connect_error());}
$sql = " SELECT * from user, category WHERE user.id='".$text_field."' or category.user_id='".$text_field."' or category.cat_id='".$text_field."'";
$rows = $result->fetch_array(MYSQLI_ASSOC);
foreach($rows as $row){
print_r($row);
}
This should get the records and show you the response from the array.
I hope you have added primary key & foreign key relations to these tables, in-order to grab data from both the tables you have two ways, either do multiplication of both table and bring in all the data else make use of JOIN that does the same in efficient way
Hoping to have your table schema as
USER [table] having id, username, name, password
CATEGORY [table] having id, name, description, user_id
So the query will become
SELECT U.*, C.id as cat_id, C.name as cat_name, C.description as cat_desc
FROM USER U
JOIN CATEGORY C ON C.user_id = U.id
If you have user inputting data from input fields, that becomes a filter query to be added in our above query, assume user is entering Name of category and wants the result set of the same then the above query gets added with WHERE clause as below
WHERE C.name LIKE '%{INPUT FIELD CONTENT HERE}%'
I have used LIKE clause above to allow us doing PARTIAL search
Hope this helps you

PHP- select specific row from MySQL database

I Need to select a specific row from a MySQLi database based off of a value in it.
For example I have a Table with a column named "house", and under that column there are maybe 5 rows with the title "house1" and three rows with the title "house2". I only want to select the rows that have "house1" in them.
This is my code
$query = "SELECT * FROM Hockey WHERE house = house1 ORDER BY attendance desc";
I then want it to make a table with only values from a row if the house is Jacksons
right now if I delete the WHERE part from my query it will make a table but it will have rows from both houses (Jacksons and Martlands)
Thanks!
$query = "SELECT * FROM Hockey WHERE house = 'house1' ORDER BY attendance desc";

MySQL inner join table gives repetaed value from unique table

Hello i have two tables with a PK---->FK Relationship in InnoDB Engine---->MySQL&PHP
The Relationship is one---->many between first table which is 'Properties' and second
table which is 'propertyimages'. every row in first table is unique but in second table
every row of first table has got many rows in second table How can i **SELECT unique row from
first table and all info about first table from second table here is my query:
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
propertyimages.ImagePath
FROM properties
INNER JOIN propertyimages
ON properties.PropertyImageID=propertyimages.PropertyImageID
AND propertyimages.PropertyImageID=8;
it gives result:
PropertyName PropertyStatus Propertyid property Image Path
Appartment For Lease 8 upload/hydrangeas.jpg
Appartment For Lease 8 upload/jelsh.jpg
Appartment For Lease 8 upload/penguins.jpg
Appartment For Lease 8 upload/tulips.jpg
In this result the PropertyName and PropertyStatus is Repeated but i want a
unique as its stored in the first tableThe propertyName and PropertyStatus
belongs to first table.The Propertyid and PropertyImagepath belings to second table.
unfortunately a join will create a record for each element found in table 2 with a matching parent element (id 8) in the first table.
you could use a GROUP BY id 8 on the first table field, but you may not get all the results you want since it will take the first image only.
could you restructure your process so that when it comes to the images (and thier display) you could just run a single query to get every image related to property 8
you could always use a nested query (presuming you're looking to display images on a page for a property, etc)
$query1 = mysql_query("SELECT Propertyid, PropertyName, PropertyStatus FROM properties WHERE (search criteria)");
if (mysql_num_rows($query1) > 0) {
while ($q1Row = mysql_fetch_array($query1)) {
// Insert property specific data here before you display the images
echo $q1Row['PropertyName']."<br>\n";
echo $q1Row['PropertyStatus']."<br>\n";
$query2 = "SELECT PropertyImageID, ImagePath FROM propertyimages WHERE PropertyImageID='".$q1Row['Propertyid']."'"
if (mysql_num_rows($query2) > 0) {
while ($q2Row = mysql_fetch_array($query2)) {
// add code here to do whatever you want with the images
echo '<image src="'.$q2Row['ImagePath'].'"><br>\n';
}
}
}
}
}
it would also help to know your DB structure .. i'd imagine you'd want something like this
table 1 (properties)
PropertyID (Primary Key)
PropertyName
PropertyStatus
table 2 (propertyImages)
ImageID (Primary Key)
PropertyID (many to one reference to PropertyID in table 1)
ImagePath
I may be a bit oblivious to the FK method so if there is a lesson here for me as well, i'd love to hear what input you have.
you are one step away from the solution, you just need to select from second table and then for first so you will have all you result matched
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
propertyimages.ImagePath
FROM propertyimages
INNER JOIN properties
ON propertyimages.PropertyImageID = properties.PropertyImageID
AND propertyimages.PropertyImageID=8;
You could achieve this with GROUP_CONCAT. But I also think, it is better to make two queries. Nothing wrong with that.
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
GROUP_CONCAT(propertyimages.ImagePath)
FROM properties
INNER JOIN propertyimages
ON properties.PropertyImageID=propertyimages.PropertyImageID
AND propertyimages.PropertyImageID=8;
GROUP BY propertyimages.PropertyImageID

Categories