MySQL Dynamic Select Box - php

I have two tables in MySQL, (and using PHP) which look similar to below:
------------------------
| |
| sizes | <--- This table is what populates the Select Box
| |
------------------------
| id | name |
| | |
| 1 | Small |
| 2 | Medium |
| 3 | Large |
------------------------
----------------------------------------
| |
| user_entries | <--- This table relates to above by "size_id"
| |
----------------------------------------
| id | user_id | size_id |
| | | |
| 1 | 25 | 2 |
| 2 | 12 | 3 |
| 3 | 15 | 3 |
----------------------------------------
My question is: How can I write my SELECT statement to both populate a select box with all the size options (Small, Med, Large) AND pre-select the option based on the user's preference.
For example, for the user with user_id=25, the HTML would look like:
<select>
<option>Small</option>
<option selected="selected">Medium</option>
<option>Large</option>
</select>

SQL is:
SELECT s.id, s.name, ue.id as UserSelected
FROM sizes s
LEFT JOIN user_entries ue ON s.id=ue.size_id AND ue.user_id=XXX
ORDER BY s.id
(Set the order as you want)
The, when you run through the results, if "UserSelected" is not NULL (i.e. has a value) then you have the selected entry.
SQL tips: try to keep column names the same between tables, so that "size_id" is the name of the id field in the size table as well as the foreign key in user_entries table; this way, you wouldn't have two "id" columns in this query that would cause problems.
You also probably don't need the "id" column in the user_entries table as you'll always search/update based on user_id? Just one less column/index to handle if you don't need it.

// get size id from user entries table based on user id
$result2= mysql_query("SELECT size_id from user_entries where user_id='$user_id'");
$row2 = mysql_fetch_assoc($result2);
$sel_size_id =$row2['size_id'];
//dropdownlist query
$query="SELECT name,id FROM sizes";
/* You can add order by clause to the sql statement if the names are to be displayed in alphabetical order */
$result = mysql_query ($query);
//populate the dropdownlist
while($row = mysql_fetch_assoc($result)) {
//determine if the size id is selected
$selected = ($row['size_id '] == $sel_size_id ) ? ' selected="selected" ' : NULL;
echo '<option value="' . $row['size_id']. '"' . $selected . '>'.$row['name'].'</option>\n';
}

Related

PHP, MYSQL, select results based on all values from 3 dropdowns being true

I have 2 drop-down lists and one select box, Country (dropdown), region (dropdown), gender (select box x 2).
my database looks like this (i have cut down the number of values)
| id | england | usa | west | north | male | female | name | age |
| 1 | 1 | 0 | 1 | 0 | 0 | 1 | John | 33 |
| 2 | 0 | 1 | 0 | 1 | 0 | 1 | John | 56 |
Apart from the ID and additional values each value i need to query will be 1 or 0 (true or false)
the result i need is if someone selects england, west, male it brings back every row which has those values as true (their is extra information on these rows i need to display)
I just need some pointers on how to achive this i was thinking of using a lookup table but am struggling to use lookup table with multiple values, or do i just use php and set each value to its correct row name and do a query like that
First of all
I suspect you are mixing the schema (column names) and the values up in your database.
Your table should be more like
|id | country |region | gender |
--------------------------------
| 1 | usa | north | male |
| 1 | england | south | female |
Think about what properties the thing has that you're trying to model.
You already kind of have this in your drop-downs. Each drop-down has a list of possible values for that property.
While you're at it, you should probably go further and split your data into more tables.
countries
|id | name | other | columns | about | countries | eg. iso_code|
------------------------------------------------------------------
| 1 | USA | .... | ..... | ..... | ...... | us |
| 2 | England| .... | ..... | ..... | ...... | uk |
regions
| id | name |
------------------
| 1 | north |
| 2 | south |
| 3 | east |
| 4 | west |
| 5 | south-west|
| .. | ....
users
|id | name | country_id |region_id | gender |
---------------------------------------------
| 1 | John | 1 | 1 | m |
| 2 | Mary | 2 | 4 | f |
You would then have to come up with ways of converting your data form the old system into the new.
First take over some of the data from the original table
INSERT INTO new_users (id,name) SELECT id, name FROM old_users;
This will insert the names with the same IDs as the original table in the new table.
Create the data for the lookup tables (country and region in this case)
INSERT INTO countries (name,iso_code) VALUES
('USA','us'),
('United Kingdom','uk'),
....
Then update your fields
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.country_id = 1 WHERE old_users.usa =1;
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.country_id = 2 WHERE old_users.england =1;
...
etc...
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.region_id = 1 WHERE old_users.north =1;
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.region_id = 2 WHERE old_users.west =1;
...
Once you have that sorted...
Your drop-downs should be something like.. (you can generate the dropdowns automatically from your lookup tables (e.g. countries) by listing all the values with their names)
When you add new countries to the table, they will automatically appear in the drop-down from now on.
<?php
....
while ($resultrow = $result->fetch_assoc()){ ?>
<option value="<?php echo $resultrow['id'] ?>">
<?php echo $resultrow['name']; ?></option>
}
You should end up with something like the following in your html output.
<select>
<option value="1">USA</option>
<option value="2">UK</option>
</select>
Then your search query should look something like this:
$sql ="SELECT * FROM table
WHERE `country_id`= '$country_id'
AND `region_id`= '$region_id'
AND `gender`= '$gender'";

Return multiple labels for a field with multiple values

I have a function that runs and gets the labels from a lookup table for values stored in a particular table. When there is 1 value it displays correctly. However when there is multiple values it only returns the first one. For example:
Lookup table is
| Tel_No| Tel_type |
--------------------
| 1 | Info |
| 2 | Support |
| 3 | Call |
Main table is
| TelephoneCalls |
------------------
| 1,3 |
| 3 |
| 1,2,3 |
The function I have at the moment which works for matching 1 value is
function getMonitoring($monitoring){
$query = "SELECT Tel_type FROM TelephoneCalls Where Tel_no = '$monitoring'";
$result9 =mysql_query($query) or die(mysql_error());
list($Tel_type) = mysql_fetch_array($result9, MYSQL_NUM);
return $Tel_type;
}
How can I get it to list the values like below
If 1, 3 then display Info, Call
If 3 display Call
If 1, 2, 3 display Info, Support, Call
Thanks for any help!
I guess the comments touched upon it, but you really should change your schema to be more of a many-to-many relationship than using CSV values in the fields. If you can't this query should work:
SELECT telephonecalls, GROUP_CONCAT(tel_type)
FROM lookup_table
LEFT JOIN main_table ON FIND_IN_SET(tel_no , replace(TelephoneCalls,' ', '')) > 0
GROUP BY telephonecalls;
#outputs
+----------------+------------------------+
| telephonecalls | GROUP_CONCAT(tel_type) |
+----------------+------------------------+
| 1,2,3 | Info,Support,Call |
| 1,3 | Info,Call |
| 3 | Call |
+----------------+------------------------+
http://sqlfiddle.com/#!2/194fd/1/0

confusion about result structure from joining tables when each row has multiple correspondence on the second table

lets say i have a simple poll aplication
and each user only can choose one option from poll
my poll table
+-----------+---------------------+
| poll_id | question |
+-----------+---------------------+
| 1 | q1? |
+-----------+---------------------+
| 2 | q2? |
+-----------+---------------------+
| 3 | q3? |
+-----------+---------------------+
my options table
+-----------+---------------------+---------+---------+
| option_id | poll_id | option | counter |
+-----------+---------------------+---------+---------+
| 1 | 1 | yes | 254 |
+-----------+---------------------+---------+---------+
| 2 | 1 | no |392333337|
+-----------+---------------------+---------+---------+
| 3 | 2 | yes | 1000 |
+-----------+---------------------+---------+---------+
right now i do something like this to show all the polls i one page
$polls = $db->query("select * from polls ");
foreach ($polls as $poll)
{
echo $poll->question;
$options = $db->query("select * from options where poll_id = '$poll->id' ");
foreach($options as $op )
{
echo '<checkbox />'.$op->option;
}
}
now if i want to do this using joine and one query
$query = "select p.* , o.* from polls p JOIN options o ON p.poll_id = o.poll_id ";
what data structure is going to be used to represent the result ? perhaps a multidimensional array ? i'm not sure how can i printout the result
like in this example result is going to be
resul_array (
poll_id poll_question option option
1 q1 ys no
2 q2 no
}
if i get the result as an array row one would have columns with similar name ? i'm confused
In my opinion, you just need to add "order by" in your query, and store result in an array, and then process the logic on it.
Something like:
$polls = $db->query("select p.* , o.* from polls p JOIN options o ON p.poll_id = o.poll_id order by p.poll_id");
$currentPoll = $polls[0];
foreach ($polls as $poll)
{
if($poll->poll_id != $currentPoll->poll_id) {
echo $poll->question;
$currentPoll = $poll;
}
echo '<checkbox />'.$poll->option;
}
HTH.

I need to create a query using MySQL and PHP to get a result of two tables

I'm new to MySQL and PHP. I have two tables, one to hold all the company names and the other table has only the company name below the user:
Table 1
| # | Company name |
--------------------
| 1 | Microsoft |
| 2 | HP |
| 3 | Asus |
| 4 | Apple |
| 5 | Amazon |
| 6 | CCN |
table 2
| # | Company name | User name |
--------------------------------
| 1 | Asus | x1 |
| 2 | Apple | x1 |
| 3 | HP | x2 |
| 4 | Asus | x2 |
| 5 | Apple | x2 |
I need to create a query that achieves the following. First of all the companies are shown which are associated with a specific user (say Asus and Apple for user x1). After that, the remaining companies from table 1 are shown.
For example, the result of the query I'm looking for, for user X1 will display the rows in this way:
| # | Company name |
--------------------
| 1 | Asus |
| 2 | Apple |
| 3 | Microsoft |
| 4 | HP |
| 5 | Amazon |
| 6 | CCN |
How can I achieve this?
It looks like you want to include all companies, but for a given user, list the companies associated with that user first. If that's the case, you do not want to use an INNER JOIN.
Here's some SQL that should work. I've provided reasonable table and field names since you didn't give those. I'm also assuming that you have a reasonably sane table design with no duplicate rows.
SELECT c.company_name,
CASE
WHEN u.company_name IS NULL THEN 'N'
ELSE 'Y'
END AS user_has_company
FROM companies c
LEFT JOIN (
SELECT *
FROM users
WHERE user_name = 'x1'
) u
ON u.company_name = c.company_name
ORDER BY user_has_company DESC, c.company_name
This query will return an extra column - user_has_company. I'd use that to indicate whether the current user is associated with a given company, but you can ignore it if you want.
You will need a JOIN Statement to join another in the SELECT-Statement of table1
Quick example:
SELECT * FROM table2 INNER JOIN table1.id = table2.id WHERE table2.username = 'x1'
You'll find everything you need in the Documentation of JOINs.
http://dev.mysql.com/doc/refman/5.1/en/left-join-optimization.html
If you're just after the MySQL query for this then something like this would work
SELECT company_name,SUM(IF(user_name='x1',1,0)) as ordering
FROM `table2`
GROUP BY company_name
ORDER BY ordering DESC
But you should look at your schema before you go much further. If you have a column (company_name) in one table that refers to another table you should make that column refer to the PRIMARY KEY of the other table, i.e.
Table1
| # | company_name |
--------------------
| 1 | microsoft |
| 2 | hp |
| 3 | asus |
| 4 | apple |
| 5 | amazon |
| 6 | CCN |
table2
| # | company_id | user_name |
--------------------------------
| 1 | 3 | x1 |
| 2 | 4 | x1 |
| 3 | 2 | x2 |
| 4 | 3 | x2 |
| 5 | 4 | x2 |
This is one of the first things you learn in database design/normalisation. You will need to change your query in this case. Something like this:
SELECT company_name,SUM(IF(user_name='x1',1,0)) as ordering
FROM `table1`
LEFT JOIN `table2` ON table2.company_id=table1.id
GROUP BY company_name
ORDER BY ordering DESC
Create your query like this:
$sql = "SELECT b.companyName FROM table1 a INNER JOIN table2 b ON a.companyName = b.companyName WHERE b.userName = 'x1'";
Then, using PHP, use:
$con = mysql_connect("localhost","peter","abc123");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("my_db", $con);
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row['companyName'];
echo "<br />";
}
mysql_close($con);
Try this query:
SELECT company_name FROM table2 ORDER BY user_name ASC
In the HTML table, using PHP code:
$result = mysql_query(" SELECT company_name, user_name FROM table2 ORDER BY user_name ASC");
echo "<table>
<tr><th>Company Name</th><th>username</th></tr>";
while($row = mysql_fetch_array($result) {
echo "<tr><td>{$row['company_name']}</td><td>{$row['user_name']}</td></tr>";
}
echo "</table>"

Show database entries separated by comma

I have one field in the backend, where I input IDs separated by comma - ID1, ID2, ID3....These are videos in fact. All ids are stored in the field product_videos in the database (as they are typed).
How can I echo these id's on the frontend so they all show for the product?
Storing comma separated data in one data field is a bad idea. It is a real pain to manipulate, so you should really consider revising your db structure.
You haven't shown your data structure, so I'll give a basic example and then explain how it can be improved. My example assumes product_videos is linked to particular users:
table: `users`
| user_id | user_name | product_videos |
|---------|-----------|----------------|
| 1 | User1 | 1,2,3,4,6,7 |
| 2 | User2 | 5 |
You would maybe run a query
SELECT `product_videos` FROM `users` WHERE `user_name` = 'User1'
This would give you one row, with a comma separate value - you would then need to use something like PHP's explode() to convert it into an array and then loop through that array. That is a very bad method (and it will only become harder as you try to do more advanced things).
Instead, it would be easier to use a link table. Imagine:
table: `users`
| user_id | user_name |
|---------|-----------|
| 1 | User1 |
| 2 | User2 |
table: `videos`
| video_id | user_id |
|-----------|---------|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 1 |
| 7 | 1 |
In this example, each video is a separate row in a db table (and each video is linked to an existing user). Each row is readily able to be handled independently. This makes it really easy to handle extra data for each video, such as a title, runtime length, date of uploading, etc.
You would then need to run a JOIN query. e.g.
SELECT `videos`.`video_id` FROM `videos`
INNER JOIN `users` ON `users`.`user_id` = `videos`.`user_id`
WHERE `users`.`user_name` = 'User1'
In PHP, you would do something like:
$q = mysql_query("SELECT `videos`.`video_id` FROM `videos` INNER JOIN `users` ON `users`.`user_id` = `videos`.`user_id` WHERE `users`.`user_name` = 'User1'");
while ($row = mysql_fetch_assoc($q)) {
echo "VIDEO ID = " . $row["video_id"] . "<br/>";
}

Categories