I'm back with another Laravel issue that I can't seem to crack with my procedural PHP, direct mysql_query background. It basically involves the Eloquent ORM over multiple tables.
I have 3 tables (Users, User_Profiles, and User_Answers). The Users table only keeps the very basics of the user (auto_incremented id, email, password), the User_Profiles table contains a few more details (image url, country, city, gender, etc) and belongs_to the User model. The User_Answers table is a list of answers given by the user and also belongs_to the User model.
What I would like to do is select all rows from the User_Profiles table where the city is the same as the city of the logged-in user, get their user_id's in an array and then compare the answers (from the User_Answers table) to the answers of the currently logged in User. The following is what I'm looking to do but in plain PHP and (for explanation purposes only) mysql_query. I apologize in advance for the awful code. I just need to be pointed in the right direction.
<?php
$link = mysql_connect("localhost", "xxx", "xxx");
$db = mysql_select_db('testersize', $link);
$id = 2;
$sql = "SELECT city FROM user_profiles WHERE user_id = $id";
$query = mysql_query($sql, $link);
$row = mysql_fetch_row($query);
$city = $row[0];
echo $city . "</br>";
$sql = "SELECT user_id FROM user_profiles WHERE city = '$city'";
$matches = mysql_query($sql, $link);
//
while($row = mysql_fetch_row($matches)){
$u_id = $row[0];
$sql = "SELECT books, movies, music FROM user_answers WHERE user_id = $u_id";
$query2 = mysql_query($sql, $link);
$row2 = mysql_fetch_row($query2);
echo "<h2>User Number: " . $u_id . "</h2>";
echo "your favorite books:" . $row2[0] . "</br>";
echo "your favorite movies:" . $row2[1] . "</br>";
echo "your favorite music:" . $row2[2] . "</br>";
}
?>
$user_profiles = User_Profiles::where('city','=',Auth::user()->city)->get();
foreach($user_profiles as $user_profile){
$id = array('user_id'=>$user_profile->user_id);
}
So that code will get you the user_profiles by city and then loop through them and put their in an array , im not sure what do you mean by match answers to users table though..
$user_ids = User_Profiles::where('city','=',Auth::user()->city)->lists('user_id');
$favorites = User_Answers::whereIn('user_id',$user_ids)->get();
foreach($favorites as $favorite)
{
echo $favorite->book;
echo $favorite->music;
echo $favorite->movie;
}
Related
I am new to PHP coding and just trying to fix some functionality on my site that was left over from the lead developer.
The site, [Vloggi], is a marketplace. So I need to show the name of the job poster in the assignments page . The table I have the jobs in only has the ID, not the name.
So I need a join, but I've tried and it breaks the entire site.
The SQL has 17 tables, I need to display the User Name (usr_name) contained in table 3, the organisation contained in table 7 (usrg_orgname) with the job posting user (vlop_usr_id) details in table 14.
The primary key is users.usr_id, which is linked to users_gor.usrg_usr_id and vlog-ops.vlog_usr_id.
Table 3: users
usr_id, usr_email, usr_password, usr_fbuser, usr_fbtoken, usr_name, usr_loc_name, usr_loc_lat1, usr_loc_lon1, usr_loc_lat2, usr_loc_lon2, usr_status, usr_gor, usr_vgr, usr_token, usr_regtoken,
table 7: users_gor
usrg_usr_id, usrg_creditops, usrg_creditvlog, usrg_creditvlogette, usrg_destination, usrg_orgname, usrg_orgtype, usrg_location, usrg_website, usrg_jobtitle, usrg_phone, usrg_address1, usrg_address2, usrg_state, usrg_postcode, usrg_country
Table 14: vlog-ops
vlop_id, vlop_title, vlop_description, vlop_tags, vlop_deadline, vlop_quantity, vlop_quantityposted, vlop_vser_id, vlop_usr_id,vlop_loc_name, vlop_loc_lat1, vlop_loc_lon1, vlop_loc_lat2, vlop_loc_lon2, vlop_campaign, vlop_rules, vlop_tips, vlop_status
So in main.php i have written the following Sql lookup
in main.php, I have the following SQL lookups:
$sql = "SELECT * FROM users_gor WHERE usrg_usr_id = ".$db->quote($user_info['usr_id'])." LIMIT 1";
$rows = $db->select($sql);
$users_gor = $rows[0];
$sql = "SELECT * FROM users_vgr WHERE usrv_usr_id = ".$db->quote($user_info['usr_id'])." LIMIT 1";
$rows = $db->select($sql);
$users_vgr = $rows[0];
$sql = "SELECT * FROM users WHERE usr_id = ".$db->quote($user_info['usr_id'])." LIMIT 1";
$rows = $db->select($sql);
$users = $rows[0];
$sql = "SELECT * FROM vlog-ops WHERE vlop_usr_id ".$db->quote($user_info['usr_id'])." LIMIT 1";
$rows = $db->select($sql);
$users = $rows[0];
$sql = "SELECT usr_name AS vlop_usr_name FROM users WHERE usr_id = ".$db->quote($user_info['usr_id'])." LIMIT 1";
$rows = $db->select($sql);
$users = $rows[0];
And then in the page template itself, I have written
<?php echo $vlop['vlop_vser_id'] ?>
<?php echo $vlop['vlop_usr_name'] ?>
The first one works, the second doesn’t. What I want eventually is to display the user name and the organisation name in a table.
Whenever I try a JOIN or a NATURAL JOIN or a LEFT JOIN it breaks and the entire site goes blank.
Any help for a newbie would be appreciated with a million thanks.
When you use JOIN you need to specify how you're joining them.
In the query below I'm assuming you're looking for the fields in bold from your question.
$query='SELECT u.usr_name, g.usrg_orgname, v.vlop_usr_id FROM users u
JOIN vlog-ops v on u.usr_id = v.vlop_usr_id
JOIN users_gor g on u.usr_id = g.usrg_usr_id';
I believe I got the name of the fields right but if not just replace them with the correct ones.
Once you have the data fetched, you just loop through the results:
$result = mysqli_query($connection, $query);
while($row = mysqli_fetch_assoc($result)) {
echo 'User name = ' . $row['u.usr_name'];
echo 'Org name = ' . $row['g.usrg_orgname'];
echo 'Job posting user id = ' . $row['v.vlop_usr_id'];
}
Database_name1(Criteria) -> table_name(tenantCriteria) and inside I have the following columns
-username
-firsrent
-occupation
-age
-tenantgender
-income
-history
-address
-tenantsmk
-tenantpet
Database_name2(Tenant) -> table_name(preference) and inside I have the following columns
-username
-firsrent
-occupation
-age
-tenantgender
-income
-history
-address
-tenantsmk
-tenantpet
3.Database_name3(Ad) -> each table has the usernames name, hence table_name($username) and inside we have the following columns
-adtype
-roomtype
-negotiable
-price
-include
-title
-address1
-address2
-postcode
-city
-province
-image
-description
If the user that log in's is a tenant, and he wants to see all the property for sell, she click on the rentalmatch button and what that button is supposed to do is to check the similarities between the tenants preference table and go through all the tables in the Criteria database and return all the username from the Criteria database that have at least on similarity with the tenants preference. Once it returns all the usernames I want to go to database *(Ad) where the tables have the usernames name that we found before. We go inside that usernames table and show all the property that that user is selling.
so far this is what I have:
<?php
$conn = mysqli_connect("localhost", "root", "root");
$sql = "
SELECT t.username
FROM Criteria.tenantcriteria AS t
JOIN Tenant.preference AS p
ON t.firstrent = p.firstrent OR t.occupation = p.occupation OR t.age = p.age
OR t.gender = p.gender OR t.income = p.income OR t.history = p.history
OR t.address = p.address OR t.smoker = p.smoker OR t.pet = p.pet
WHERE p.username = $username";
$result = mysqli_query($db,$sql) or die(mysql_error());
?>
From here on out what should I do? Is the php good? if not what should it be?
This will show all the properties in an HTML list, you could use a <table> instead.
echo "<ul>";
while ($row = mysqli_fetch_assoc($result)) {
$owner = $row['username'];
echo "<li>Owner: $owner<ul>";
$owner_query = mysqli_query("SELECT * FROM Ad.$owner");
while ($property = mysqli_fetch_assoc($owner_query)) {
echo "<li><dl>";
foreach ($property as $col => $val) {
echo "<dt>$col</dt><dd>$val</dd>";
}
echo "</dl></li>";
}
echo "</ul></li>";
}
echo "</ul>";
<?php
mysql_connect("localhost", "root", "");
mysql_select_db("students");
$id = $_POST['id'];
$grade = $_POST['grade'];
$query = "INSERT INTO `st_table` (`St_id`,`Grade`) VALUES ('$id','$grade')";
$result = mysql_query($query);
$query = "SELECT * from `st_table`";
$result = mysql_query($query);
echo "<table>";
echo "<th>St_id</th><th>Grade</th>";
while($row = mysql_fetch_array($result)){
echo "<tr><td>" . $row['St_id'] . "</td><td>" . $row['Grade'] . "</td></tr>";
}
This code adds values into a table both ID and Grade. I want another query that will be able to count how many As, Bs, Cs, etc. and OUTPUT it on an html table.
Here, Your query is ok just group by Grade not Grades
"SELECT `Grade`, COUNT(*) AS count FROM `st_table` GROUP BY `Grade`";
Here is sqlfiddle
After edit
The query i am mentioning should work for you, you can check fiddle for that as for as you modified code is concerned you have to change your table a bit since you are going to include St_id as well so make it 3 column and correspondingly change query too.
Let's assume I a have a table called "users" which has the following relevant columns:
username
zipcode
Let's also assume I have a table called "shops" which has the following relevant columns:
shop_name
zipcode
Let's also assume I have a table called "preferred_shops" which has the following relevant columns:
shop_name
username
Let's also assume I have a table called "zipData" which has the following relevant columns:
zipcode
lat
lon
Currently I can run this code with success:
$lat="49.886436"; // Value should be obtained from the zipData table by doing a "SELECT FROM zipData WHERE zipcode=(users_zip_code)" or similar query
$lon="-97.14553"; // Value should be obtained from the zipData table by doing a "SELECT FROM zipData WHERE zipcode=(users_zip_code)" or similar query
$radius=5;
$query="SELECT zipcode FROM zipData
WHERE (POW((69.1*(lon-\"$lon\")*cos($lat/57.3)),\"2\")+
POW((69.1*(lat-\"$lat\")),\"2\"))<($radius*$radius)";
The query above will successfully display all the other zip codes that are within the given radius of the supplied lat/lon but I have no interest in knowing what other zip codes there are... I want to know what shops are within the radius.
Any help you can give would be greatly appreciated.
==== Edited because I realized it is actually a little more complex ====
This is what I need to do...
Retrieve the user's zipcode from "users" table
Find the user's lat/lon from the zipData table
Find all the shops within a given radius that is also in a "preferred_shops" table with the given user in the "username" column
Problems to consider: the zipcode in "zipData" has no white space but the zipcodes in "users" and "shops" have white space for cosmetic reasons... such as Canadian Postal codes which are in the "A1A 1A1" format
==== Edited to post solution ====
The system says I am not allowed to answer my own question. That sounds strange since with the help of others I already found the answer. As a work around I am editing the original post. Here is the solution...
Ok so I figured it out (with the help of the people that replied)... This is what I did.
IT LIKELY COULD BE A LOT SHORTER AND CLEANER SO PLEASE FEEL FREE TO MAKE IT BETTER IF YOU KNOW A BETTER WAY.
$query = "SELECT * FROM preferred_shops
WHERE `username`='{$_SESSION['account_name']}'
";
$result = mysql_query($query);
if (mysql_errno())
{
die( "ERROR ".mysql_errno($link) . ": " . mysql_error($link) );
}
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_array($result))
{
// Get user's preferences and postal code
$query2 = "SELECT * FROM seekers
WHERE `username`='{$_SESSION['account_name']}'
";
$result2 = mysql_query($query2);
if (mysql_errno())
{
die( "ERROR ".mysql_errno($link) . ": " . mysql_error($link) );
}
$num_rows2 = mysql_num_rows($result2);
$row2 = mysql_fetch_array($result2);
$radius=$row2['radius']; // Didn't mention that is column was in the table but that didn't matter... the value could have come from anywhere.
// Get user's lat/lon
// Remove white space from the postal code
$query3="SELECT * FROM zipData WHERE zipcode=replace('{$row2['postal']}',' ','')";
$result3 = mysql_query($query3);
if (mysql_errno())
{
die( "ERROR ".mysql_errno($link) . ": " . mysql_error($link) );
}
$num_rows3 = mysql_num_rows($result3);
$row3 = mysql_fetch_array($result3);
$lat=$row3["lat"];
$lon=$row3["lon"];
$query4="SELECT shop_name FROM zipData,shops
WHERE (POW((69.1*(lon-\"$lon\")*cos($lat/57.3)),\"2\")+POW((69.1*(lat-\"$lat\")),\"2\"))<($radius*$radius)
AND replace(shops.zipcode,' ','') = zipData.zipcode
AND shops.shop_name={$row['shop_name']}
";
$result4 = mysql_query($query4);
if (mysql_errno())
{
die( "ERROR ".mysql_errno($link) . ": " . mysql_error($link) );
}
$num_rows4 = mysql_num_rows($result4);
$num_jobs=$num_rows4;
$i=0;
while($row4 = mysql_fetch_array($result4))
{
$shopArray[$i]=$row4["shop_name"];
$i++;
}
var_dump($shopArray);
}
You need to join to the shops table
SELECT shop_name FROM zipData,shops
WHERE (POW((69.1*(lon-\"$lon\")*cos($lat/57.3)),\"2\")+
POW((69.1*(lat-\"$lat\")),\"2\"))<($radius*$radius) and
shops.zipcode = zipdata.zipcode
select shopname from shops where zipcode in ( <your other working query> )
I am making an application that displays "activities". Each activity has his own button. When you click on that button, you add that specific activity to your "guide". The idea is that you can add one specific activity only once, so the button of that activity must disapear when it's added to the guide. I can use a simple $(this).hide() in my javascript but that obviously doesn't work when I refresh the page. So I guess i should make a check if the activity exists in de guide.
in the database I have 3 tables, 1: activity (with an ActivityID), 2: user (with a UserID) and 3: user_activity (with ActivityID and UserID, a linktable).
So the check must check if the ActivityID exists in the user_activity table, and that the UserID that belongs to that ActivityID in the user_activity table is the sames as the current users' ID.
At this moment, I know how to check the current users UserID:
//userid
$sql = "SELECT * FROM user WHERE Username = '".$_SESSION['Username']."' ";
$stm = $db->prepare($sql);
$result = $stm->execute(array());
while($row = $stm->fetch(PDO::FETCH_ASSOC)) {
$userid = $row['UserID'];
}
But I don't know how to check if the ActivityID already exists, and how I should make this
if else statement.
Ay the moment I use this script to display the activity (incl. the button)
$sql = "SELECT * FROM activity";
$stm = $db->prepare($sql);
$result = $stm->execute(array());
while($row = $stm->fetch(PDO::FETCH_ASSOC))
{
echo '<div id="activity'.$row['ActivityID'].'">';
echo '<img src="data:image/jpeg;base64,' . base64_encode( $row['ActivityIMG'] ) . '" >', '<br>';
$instantguide = $row['ActivityID'];
echo '<input type="button" class="addActivity" onclick="MakeRequest(' . $instantguide . ')" value="Activiteit toevoegen" data-activity="' . $row['ActivityID'] . '">';
echo '</div>';
}
You need a LEFT JOIN to see what activities are already on
SELECT a.*, ua.ActivityID as added
FROM activities a LEFT JOIN user_activity ua
ON a.ActivityID=ua.ActivityID AND UserID=:userid
So you'll have an additional added field in the resultset, filled with an id if it is already chosen or empty otherwise
// First you need to get all the activityIDs from the table where you want to search and put them into an array
$sql2 = "SELECT * FROM user_activity";
$stm2 = $db->prepare($sql2);
$result2 = $stm2->execute(array());
$user_activityID = array();
while($row2 = $stm->fetch(PDO::FETCH_ASSOC))
{
// if in the table user_activity the column you are trying to compare has the same name as in activity -- $row2['ActivityID']
array_push($row2['ActivityID'], $user_activityID);
}
// Then you use in_array to compare while you go through the user_activity table
$sql = "SELECT * FROM activity";
$stm = $db->prepare($sql);
$result = $stm->execute(array());
while($row = $stm->fetch(PDO::FETCH_ASSOC))
{
if (in_array($row['ActivityID'], $user_activityID))
{
// yes the current $row['ActivityID'] from the activity table, exists in the user_activity table
// you can choose whether or not to add this to your array
array_push($row['ActivityID'], $activityID);
}
}
I'm sure there's other more efficient ways to do this, using some pdo stuff that I don't know, but this is how I would have done it.