php codeigniter mysql joins - php

Ok so im working on my first ever php/mysql project having come from a software position. I am learning codeigniter and i have worked out that this mysql join will get me friends statuses based on an user.id, how do i add in all my posts to that do i have to do an AND query?
select * from friendships
join users on users.`id` = friendships.`friend_id`
join statuses on statuses.`user_id` = users.id
where friendships.`user_id` = 2
ORDER BY statuses.`id` desc
Any help greatly appreciated

Join query in codeigniter can be written as:
$this->db->select("*");
$this->db->from("friendships");
$this->db->join("users","users.id = friendships.friend_id");
$this->db->join("statuses","statuses.user_id = users.id");
$this->db->where("friendships.user_id",2);
$this->db->order_by("statuses.id","desc");
$result=$this->db->get();
or
$this->db->select("*");
$this->db->join("users","users.id = friendships.friend_id");
$this->db->join("statuses","statuses.user_id = users.id");
$this->db->where("friendships.user_id",2);
$this->db->order_by("statuses.id","desc");
$result=$this->db->get("friendships");

Well, CodeIgniter abstracts DB interaction through ActiveRecord (so writing full SQL query strings really isn't necessary). They do a better job of explaining it than I could:
http://ellislab.com/codeigniter/user-guide/database/active_record.html

Why not just add each user as a follower of themselves in your friendships table? So on registration you add them to users table and to the friendships table.
User 1 follows User 1 etc

You can also use this query in codeigniter
$query = $this->db->query("select * from friendships
join users on users.`id` = friendships.`friend_id`
join statuses on statuses.`user_id` = users.id
where friendships.`user_id` = 2
ORDER BY statuses.`id` desc");
$result = $query->row_array();

Related

Left Join between two databases using PDO

I have two databases and I am trying to compare two tables. My code does not seem to be working, not sure what I am doing wrong.
Here is the code.
<?php
include 'connection.php';
/*
* This code compares between two tables
*/
//SQL call
$getData = $connection->prepare("SELECT `CustomerCity` FROM `auth` LEFT JOIN `tb_data.cobs.city` WHERE `CustomerCity` = `tb_data.cobs.city` LIMIT 3");
$getData->execute();
$gotData = $getData->fetchAll(PDO::FETCH_ASSOC);
print_r($gotData);
In my database I have two tables, on is cobs, the other is tb_data. tb_data has a table called cobs and auth is a table within a database called d_data. Both of these tables have a city column. I need get every record in auth that has a city that matches in the cobs table.
That looks like the query is using a mixture of explicit join syntax with obsolescent syntax for the join using the WHERE clause for the join conditions.
If so try:-
SELECT CustomerCity
FROM auth
LEFT JOIN tb_data.cobs
ON auth.CustomerCity = cobs.city
LIMIT 3
Others have pointed out that your query is wrong, but have not provided a correct answer. This is what you are likely looking for:
SELECT `auth.CustomerCity` FROM `auth`
LEFT JOIN `tb_data.cobs` ON `tb_data.cobs.city` = `auth.CustomerCity`
LIMIT 3
Try this :
Select *.auth, *.cobs from auth join cobs on auth.city = cobs.city limit 3
The query is incorrect, you need to specify the link betweeen the tables auth and tb_data.cobs.city. For example:
SELECT
*
FROM
FOOTABLE FOO
LEFT JOIN
BARTABLE BAR ON BAR.FOO_ID FOO.ID = -- here goes the link between them
WHERE
...

mysql multiple WHERE from different tables

I want to output a nice user table. But my query needs a WHERE from multiple tables.
At the moment... my query looks like:
$statsTable = "someTable";
$userTable = "someOtherTable";
$someData = "SELECT stats.* FROM $statsTable stats, $userTable user
WHERE user.some_status = '0'
AND (stats.some_value BETWEEN $rangeFrom AND $rangeTo)
ORDER BY stats.some_value ASC
LIMIT 0,10";
then mysqli_query and so on...
The output(array) has 2 times the data from $statsTable and the WHEREs are not working. I just want to select the $statsTable...
How to proceed?
Thanks :)
$statsTable = "someTable";
$userTable = "someOtherTable";
$someQueryForData = "SELECT stats.*
FROM $statsTable stats
JOIN $userTable user
ON (user.id_stats = stats.id)
AND (user.some_status = '0')
WHERE (stats.some_value BETWEEN $rangeFrom AND $rangeTo)
ORDER BY stats.some_value ASC LIMIT 0,10";
Edit: explaining you're basically need a join, building query's the way you are doing makes them not as readable and you can't really associate your tables.
Using joins after you made your "ON" statement you may just add an "AND"
And use that conjunction as a where which is way faster the using the where ITSELF
Just use a join.
Join the tables on a unique ID and then you will have the values from both tables.
W3 Schools Joins
Should look like this
SELECT stats.* as stats, user.* as user
FROM statsTable
INNER JOIN userTable
ON stats.userId=user.userId
WHERE user.some_status = 0 AND (stats.some_value BETWEEN $rangeFrom AND $rangeTo)
LIMIT 0,10;

How to not select an id that is listed in another table from an adjoining table in SQL?

A little more background on my issue. I have a "Followers" sidebar on my site where users can follow other users. The problem is that currently the users that appear in this sidebar can also include users they already follow. I would like to modify the function so this no longer happens. Here is the model function that I currently use...
public function get_oldest($limit = 10, $user_id)
{
$this->db
->select($this->db->dbprefix('profiles').'.*, g.description as group_name, users.*')
->join('groups g', 'g.id = users.group_id')
->join('profiles', 'profiles.user_id = users.id', 'left')
->group_by('users.id');
$this->db->order_by('users.created_on', 'ASC');
$this->db->limit($limit);
$results = $this->db->get('users')->result_array();
return $results;
}
Here is the controller function...
function get_oldest() {
$this->load->model('user_account/user_account_m');
$limit = $this->attribute('limit');
$user_id = $this->current_user->id;
$users = $this->user_account_m->get_oldest($limit, $user_id);
return $users;
}
The "Follower"(default_follow) table in the sql database has the following structure...
id = the id of the follow event
follower_id = the user_id of the person who is doing the following
followed_id = the user_id of the person being followed
The "Profile"(default_profiles) table in the sql database has the following structure...
user_id
display_name
first_name
last_name
I know I need to use the current user's id in some way to get this to work, I'm just having a hard time figuring out how. Thanks in advance for your help people.
One way to do set difference in sql is the EXCEPT keyword. I put up a toy rendering on sqlfiddle here:
http://sqlfiddle.com/#!6/2308a/6
SELECT distinct user_id
FROM users
EXCEPT
SELECT followed_id
FROM follow
WHERE follower_id = <idhere>
The top sql will grab all user_id's in the system. The bottom will grab all of the people the current user is following, and the EXCEPT keyword will apply set difference to give you the all users that the current user has not followed yet.
The functionality you're looking for is called a subquery.
In SQL, your CodeIgniter ActiveRecord query roughly translates as:
SELECT profiles.*, g.description as group_name, users.*
INNER JOIN groups g ON g.id = users.group_id
LEFT JOIN profiles ON profiles.user_id = users.id
GROUP BY users.id
ORDER BY users.created_on;
To filter out existing followers, We'll add a WHERE clause to that that uses the IN keyword and a subquery:
SELECT profiles.*, g.description as group_name, users.*
INNER JOIN groups g ON g.id = users.group_id
LEFT JOIN profiles ON profiles.user_id = users.id
WHERE users.id NOT IN (SELECT follower_id FROM default_follow WHERE followed_id = ?)
GROUP BY users.id
ORDER BY users.created_on;
The ? indicates a query parameter, which in your case would be the ID of the logged-in user.
Converting back to CodeIgniter, you have a couple options:
1) Write the NOT IN clause directly into a call to CodeIgniter's "where" function, concatenating the user ID.
$this->db
->select($this->db->dbprefix('profiles').'.*, g.description as group_name, users.*')
->join('groups g', 'g.id = users.group_id')
->join('profiles', 'profiles.user_id = users.id', 'left')
->where('users.id NOT IN (SELECT follower_id FROM default_follow WHERE followed_id = '.$user_id.')', NULL, FALSE)
->group_by('users.id');
2) Break the subquery out into a separate query and use the results in the second query:
$this->subquery->select('follower_id')
->where('followed_id', $user_id);
$followers = $this->subquery->get('default_follow')->result_array();
$this->db
->select($this->db->dbprefix('profiles').'.*, g.description as group_name, users.*')
->join('groups g', 'g.id = users.group_id')
->join('profiles', 'profiles.user_id = users.id', 'left')
->where_not_in('users.id', $followers)
->group_by('users.id');
Option 1 is nice because it lets the database do all the work, but depending on where $user_id comes from, you might be opening yourself up to a SQL injection attack. You'd want to sanitize that input ahead of time.
Option 2 is safe from SQL injection, but forces PHP to do some of the work. It won't be as fast, especially for users with lots of followers. Some databases have a limit to the number of elements you can include in an explicit IN clause (notably, Oracle limits you to 1000), but it looks like you're using mySQL, which has no such limit.
I wish there was an option three, but CodeIgniter's ActiveRecord functionality doesn't offer native support for subqueries (yet). Given the above options, I'd take option 1 and make sure to protect against SQL injection yourself.
Here's a decent reference for querying with CodeIgniter ActiveRecord:
http://ellislab.com/codeigniter/user-guide/database/active_record.html

Zend Framework join

I've been struggle for hours with the follow join issue in Zend Framework.
My table(s)
Table (websites)
id
user_id
website
url
...
Table (users)
id
username
salt
password
...
Table (reviews)
id
website_id (id of website)
user_id (id from the user/owner of the website)
reviewer_id (id from the user who has reviewed the website)
review
...
What do I want to get..
To make a array with join of the review and user data is no problem, but I want also
add the website compare to the review.
I made the follow join but I won't work like I want, I have just 3 test reviews in my database and I'm getting over 12 results in my array.
My query:
$select = $this->_db->select()
->from('reviews')
->joinLeft('users', 'reviews.reviewer_id = users.id')
->joinLeft('websites', 'reviews.user_id = reviews.user_id')
->where("reviews.user_id = $user_id");
$result = $this->getAdapter()->fetchAll($select);
With kind regards,
Nicky
Try adding a groupBy to your query (untested)
$select = $this->_db->select()->from('reviews')
->joinLeft('users', 'reviews.reviewer_id = users.id')
->joinLeft('websites', 'reviews.user_id = reviews.user_id')
->where("reviews.user_id = $user_id")
->group('reviews.id');

how to get data from three tables by a join statement in mysql

In my application i have three tables, reservation, patient and sub_unit, i need to take the patient_id from reservation table and query the patient table for patient data,same time i need to take the sub_unit_id from the reservation table and query the sub_unit name from the sub_unit table... i need to put all this data in to an one array in the sequence like
patient_id, sub_unit_name, patient_name, address and pass it to the Codeigniter table class to draw a table.
How can I query three tables in the same time to query out this data? can you guys help me out?
Using code igniter syntax it can be done as follows -
$this->db->select('r.patient_id, s.sub_unit_name, p.patient_name, p.address');
$this->db->from('reservation r');
$this->db->join('patient p', 'p.id = r.patient_id');
$this->db->join('sub_unit s', 's.id = r.sub_unit_id');
$query = $this->db->get();
You can check your formed query by -
echo $this->db->_compile_select();exit;
Select r.patient_id, s.sub_unit_name, p.patient_name, p.address
from reservation r, sub_unit s, patient p
where r.patient_id = p.patient_id and r.sub_unit_id = s.sub_unit_id
The join syntax is very straightforward in SQL. You are probably looking for something like this:
SELECT reservation.patient_id,
sub_unit.sub_unit_name,
patient.patient_name,
patient.address
FROM reservation
JOIN patient ON (patient.id = reservation.patient_id)
JOIN sub_unit ON (sub_unit.id = reservation.sub_unit_id);
In MySQL, the default join is an Inner Join, which I think is what you're looking for. You may also want to look into Outer Joins which are also very useful.
it worked guys , i did it like this using Codeigniter active records ,hope you guys can use it too
function get_data(){
$sql = 'SELECT * FROM visit,patient,sub_unit WHERE visit.patient_patient_id = patient.patient_id AND visit.sub_unit_sub_unit_id = sub_unit.sub_unit_id';
$this->db->order_by("reference_number", "desc");
$query = $this->db->query($sql);
return $query;
}
thanx for all your support!

Categories