Probably a bit of a newbie question, but I'm self-taught, and I'm trying to edit some code that is out of my comfort zone, and coming unstuck. Please help!
It is a function that selects data from a MySQL database and returns an array. It uses a couple of other 'core' functions to help with the DB connections.
The original script looks like this:
class Core{
protected $db, $result;
private $rows;
public function __construct() {
$this->db = new mysqli('localhost', 'root', 'password', 'db');
}
public function query($sql){
$this->result = $this->db->query($sql);
}
public function rows(){
for($x = 1; $x <= $this->db->affected_rows; $x++){
$this->rows[] = $this->result->fetch_assoc();
}
return $this->rows;
}
}
class Chat extends Core{
public function fetchMessages(){
$this->query("
SELECT `chat`.`message`,
`users`.`username`,
`users`.`user_id`
FROM `chat`
JOIN `users`
ON `chat`.`user_id` = `users`.`user_id`
ORDER BY `chat`.`timestamp`
DESC
");
return $this->rows();
}
}
The problem is, within the fetchMessages() function in the Chat class there is a SELECT clause which JOINS the "chat" table with the "users" table to fetch the username. If, for whatever the reason, (deleted, banned, quit, etc), the user ID doesn't exist in the user table, the SELECT clause returns no results.
In order for it still to return the message if the user doesn't exist, I think I need to seperate the JOIN into 2 SELECT CLAUSES:
First, SELECT message, user_id FROM chat ORDER BY timestamp DESC;
Then, SELECT username FROM users WHERE user_id = $user_id and RETURN "Guest" if no rows are found.
(I have got the pseudo-code or logic right in my head, I just can't code it!)
My problem is, because I am using the $this-> notation, I don't know how to include a second instance inside the function. What I want to do is something like this:
public function fetchMessages(){
$this->query("
SELECT `message`, `user_id` FROM `chat` ORDER BY `chat`.`timestamp` DESC
");
$rows = $this->rows();
foreach ($rows as $row) {
$uid = $row['user_id'];
$this[2]->query("
SELECT `username` FROM `users` WHERE `user_id` = `$uid`;
");
$user = $this[2]->rows();
if ( $user['username'] == "" ) {
$username = "Guest";
} else {
$username = $user['username'];
}
$return_array[] = array($row['message'],$username);
}
return $return_array;
}
Can anyone understand what I am trying to do, and re-write my pseudo-code so that it doesn't use two '$this->'s and actually works?
I would really appreciate any help...
You simply need to change JOIN users to LEFT JOIN users.
Your current code performs an INNER JOIN, which produces result rows only when there are rows to join on both tables. A LEFT JOIN will produce results for all rows that exist on the left-hand-side table, substituting NULL for the values from the right-hand-side table when no corresponding rows exist there.
In your case, this means that you will be getting back rows for all messages, even if there is no corresponding user for some of them.
See also a visual explanation of SQL joins.
Related
I have to try two joins but this is not going to work.
code in Codeginator.
$this->db->select('concat(firstName," ",lastName) as fullnameVisitor,users.firstName,visitorId,destinationId,count,activityStatus,created,updated');
$this->db->from('interestedprofile');
$this->db->join('users','users.userId=interestedprofile.visitorId','LEFT');
$this->db->join('users','users.userId=interestedprofile.destinationId','LEFT');
$this->db->join('interestedprofile','interestedprofile.destinationId=users.userId','LEFT');
$this->db->order_by('created','desc');
return $this->db->get()->result_array();
User Table : https://i.stack.imgur.com/ppM3s.png
Interest Table : https://i.stack.imgur.com/EbQIX.png
i have to find visitedid and destinationid users firstName and lastName in Users Table.
You don't have to use the Active Record fully to do the joins. You can use regular SQL. For example,
$query = $db->query("SELECT * FROM users;");
foreach ($query->getResult('User') as $user)
{
echo $user->name; // access attributes
echo $user->reverseName(); // or methods defined on the 'User' class
}
This Code is Work For me.
Select us1.firstName,us2.firstName from interestedprofile ip join users us1 on us1.userid = ip.visitorId join users us2 on us2.userId = ip.destinationId
I want to create variable called $start. As a value I want to select one value from column called timestamp from the last row of my table called table_ex. So far I have this:
class Main {
//some other code
function dataBaseConnect(){
//well working part
}
function getTimeValue(){
$sql = "SELECT `timestamp` FROM `table_ex` WHERE id=(SELECT MAX(id) FROM `table_ex`)";
$this->start = $this->handler->query($sql, PDO::FETCH_COLUMN, 0);
}
function printVal(){
$this->dataBaseConnect();
$this->getTimeValue();
$this->messOuput = "Sth text " .$this->start;
}
}
The problem is that variable is not getting that value I wanted. Could anyone explain me where is the problem?
Maybe this will work for You:
function getTimeValue()
{
// note the table name is now used in the inner query
$sql = "SELECT `timestamp` FROM `table_ex` WHERE id=(SELECT MAX(id) FROM `table_ex`)";
$this-start = $this->handler->query($sql, PDO::FETCH_COLUMN, 0);
}
I want to delete from ‘table1’ those rows where (user_id = 5) but I should check if those posts’ (title = title1 in table2). I use Codeigniter and I get this error while trying to delete: ‘Deletes are not allowed unless they contain a "where" or "like" clause.’ Could you please help me to check what is wrong with my code below.
table1:
table2:
public function delete($title, $user_id){
$this->db->select('table1.*');
$this->db->from('table1','table2');
$this->db->where('table1.user_id', $user_id);
$this->db->where('table2.title', $title);
$this->db->join('table2','table1.post_id=table2.post_id');
$query = $this->db->get();
if ($query && $query->num_rows() > 0) {
$this->db->delete('table1.*');
$this->db->from('table1','table2');
$this->db->where('table1.user_id', $user_id);
$this->db->where('table2.title', $title);
$this->db->join('table2','table1.post_id=table2.post_id');
return true;
}
else {
return false;
}
}
Make use of subqueries.
example
#Create where clause
$this->db->select('id');
$this->db->from('table2');
$this->db->where('table2.title', $title);
$where_clause = $this->db->get_compiled_select();
#Create main query
$this->db->where('table1.user_id', $user_id);
$this->db->where("`id` NOT IN ($where_clause)", NULL, FALSE);
$this->db->delete('table1');
References
stolen from here: https://stackoverflow.com/a/16303021/1275832
about subqueries: http://www.mysqltutorial.org/mysql-subquery/
compiled select: https://github.com/NTICompass/CodeIgniter-Subqueries
After running first query you will get the set of user that you have to delete.
Run this set throw foreach loop for getting id of user and posts that you have to delete to an array.
$user_array = array();
$post_array = array();
foreach($query->result() as $query)
{
$user_array[$query->user_id] = $query->user_id;
$post_user[$query->post_id] = $query->post_id;
}
And then
this->db->where_in('user_id', $user_array)->delete('table1');
this->db->where_in('post_id', $post_array)->delete('table2');
I know that this is not the best decision. But i think that this is the most understandable.
You may use the following code to delete data from tables becasue codeigniter ignore join when you delete multiple data from multiple tables.
$sql = "DELETE t1 FROM table1 t1
JOIN table2 t2 ON t1.thing_id = t2.id
WHERE t2.otherthing_id = ?";
$this->db->query($sql, array($id));
JOINS are used to fetch data from database not used to delete data if you want to delete data from multiple table using single query then you need to use cascading in MySQl using that you can delete data also from other tables that are related to current table.
I have a feeling this is really simple. Here's the deal: I have a table with three columns. I want to take all the values in one of the columns and turn that into a list. I want to do this so I can transverse through the list. Each value in the list corresponds to a username. I want to take that username to access info about a user. Using this info, I can check which faculty the user is in and sort accordingly. This is what I've come up with:
function get_users_by_faculty($faculty) {
global $connection;
$query = "SELECT * FROM owner";
$user_set = mysql_query($query); // ERROR could not establish link to server
confirm_query($user_set);
foreach($user_set as $user) { //ERROR invalid argument
$userFaculty = get_info_by_id($user["ownerId"], "ou");
if($faculty == $userFaculty){
return $user["name"];
} else {
return NULL;
}
}
I've been quite stuck on this for a few hours.
I don't know your fields names, but I think you could do that with an sql query.
something like that :
SELECT user.id,user.name, faculty.name
FROM user inner join faculty on faculty.id = user.faculty_id
WHERE faculty.id=?
You should replace ? with your faculty id.
If you want a list of user names, you can use group concat :
SELECT GROUP_CONCAT(user.name SEPARATOR ';')
FROM user inner join faculty on faculty.id = user.faculty_id
WHERE faculty.id=?
GROUP BY faculty.id
Here's my issue: I have 3 tables, with overlapping information (specifically, the username) in each. Except the username row isn't named the same thing in every table. Because the username is specific to the user, it makes sense to get all the other information about the user based on the username. Here's what I have. (The first function returns the query, the second function returns the information in an array (or is supposed to, anyway).
function get_user_by_id($id) {
global $connection;
$query = "SELECT * FROM ownerOrganization, owner, queue_acl";
$query .=" WHERE owner.ownerId=ownerOrganization.ownerId";
$query .=" AND owner.ownerId=queue_acl.user_id";
$query .= " AND owner.ownerId ='{$id}'";
$result_set = mysql_query($query);
confirm_query($result_set);
if ($user = mysql_fetch_array($result_set)) {
return $user;
} else {
return NULL;
}
}
function get_user_id() {
if (isset($_GET['ownerId'])) {
return get_user_by_id($_GET['ownerId']);
}
}
But when I do something like, $sel_user = get_user_id(); on another page, it doesn't actually pull up any of the selected users information... I assume that this is happening because my syntax regarding working with multiple tables is incorrect. Anyway, any input would be much appreciated.
To use JOINS, take this snipcode in example :
$query = "SELECT * FROM (ownerOrganization INNER JOIN owner ON owner.ownerId=ownerOrganization.ownerId) INNER JOIN queue_acl ON owner.ownerId=queue_acl.user_id";
$query .=" WHERE owner.ownerId ='{$id}'";
Regards
I was typing what more or less what #MTranchant wrote. I would suggest renaming your columns for easier query authoring and to avoid confusion. For instance your ownerOrganization.ownerid could be named oo_ownerid, and the other columns in the table could follow that naming convention.
Also, have you run the query against the database with a hard-coded $id that you know exists?
Lastly in the query string being sent to the next page, does a ownerId parameter appear that looks like "&ownerId="?