SQL join in CodeIgniter with Active Record - php

I'm trying to wrap my head around this, but I seem to go in circles. I'm trying to list a users topics one by one, with the quotes belonging to that specific topic underneath. If that makes sense.
I have 3 tables, like so:
[USERS] user_id username
[TOPICS] topic_id user_id topic_name
[QUOTES] quote_id topic_id quote_name
I want to be able to do something like this in my view:
Username: Thomas
Topic 1: Whatever
Quotes: One quote, another quote, and a third quote, all belonging to Topic 1.
Topic 2: Another topic from Thomas
Quotes: Yes indeed, Okay thanks, I love Stack Overflow, These quotes belong to Topic 2.
But I can't get it to work, I've been trying everything, including weird stuff like:
public function get_quotes()
{
$this->db->select('*');
$this->db->from('topics');
$this->db->join('quotes', 'topic_id = quote_id');
$query = $this->db->get();
if($query->num_rows() > 0)
{
foreach ($query->result() as $row) {
$data[] = $row;
}
}
return $data;
}
Is this strange, should I instead try using 'where' instead? Something like:
$this->db->where('user', $user_id);
$this->db->where('topic', $topic_id);
$this->db->where('quote', $quote_id);
I really appreciate any help I can get, or just a finger pointed in the right direction!

Right off the bat I would ask "What is not working?", secondly I would suggest you run the profiler to show you the EXACT SQL being generated, so that you can make a valid assessment of where the ACTIVE QUERY is failing you.
To use the profiler, stick this into your controller:
$this->output->enable_profiler(TRUE);
It will result in a nice output of all DB calls, all POST vars, etc;
Reference here: http://codeigniter.com/user_guide/libraries/output.html
UPDATE
So to fully do what you want, you need a query that returns the following columns:
user_id, username, topic_id, topic_name, quote_id, quote_name
Here is the active query you want (you can also use method chaining if that is clear enough):
$this->db->select('u.user_id, u.username, t.topic_id, t.topic_name, q.quote_id, q.quote_name');
$this->db->from('users u');
$this->db->join('topics t', 't.user_id = u.user_id'); // this joins the user table to topics
$this->db->join('quotes q', 'q.topic_id = t.topic_id'); // this joins the quote table to the topics table
$query = $this->db->get();
Your result set will then be something like:
user_id | username | topic_id | topic_name | quote_id | quote_name
1 |Thomas |1 |Whatever |1 |One quote, anot...
2 |Ryan |4 |Another... |6 |To be or not to...
Once you have that result set, simply loop through the data to output it, and check to see if you have multiple quotes from the same person (say sort by user_id and do a test on the 2nd loop if its the same person, otherwise output the new users name).

If you want all of the quotes for a specific user:
$this->db->join('TOPICS t', 'u.user_id on t.user_id')
->join('QUOTES q', 't.topic_id on q.topic_id')
->where('u.user_id', $userId)
->get('USERS u');
// I always echo my queries when developing to make sure they are what i'm expecting
echo $this->db->last_query();
If you want all of the quotes for all of the users
$this->db->join('TOPICS t', 'u.user_id on t.user_id')
->join('QUOTES q', 't.topic_id on q.topic_id')
->get('USERS u');
echo $this->db->last_query();

Related

CodeIgniter MySQL count different rows

i want to count the different rows in CodeIgniter...
I have a table like this
NAME | ZIPCODE
Mike | 12345
Marc | 51233
TEST | 12345
Now i want a Result of "2" cause there 2 different Zipcodes.
I tried so much, but dont get this :(
$this->db->select('zipcode, count(*)');
$getAll = $this->db->get('ads');
echo $getAll->num_rows();
but dont get result of or anything... idk how i can make this.
Please help
//EDIT:
Okay i found it. Sorry for Question. Here is the Answer
$this->db->distinct();
$this->db->select('zipcode');
$getAll = $this->db->get('ads');
echo $getAll->num_rows();
you can use this:
$query = $this->db->query('select count(1) as x from your_table_name group by zipcode');
$row= $query->row();
$x = $row->x;
You could use group_by() in your query as follows.
$this->db->select('zipcode', 'count(*) as totalcount');
$this->db->group_by('zipcode');
$this->db->get('ads');

How to use FIND_IN_SET() query in codeigniter

I have two tables- One with attendance details and another one with student detail. The following are the table structures:
tbl_attendance
aid date attendance
1 2017-03-09 5,6,9
2 2017-04-06 12,6,10
tbl_students
student_id name
5 John
6 Bryan
9 Anna
10 Mathew
12 Susan
Now, I want to display the names of the absentees in the view as something like say. for example:
Date Absentees
2017-03-09 John, Bryan, Anna
2017-03-06 Susan, Bryan, Mathew
I was trying to do it with FIND_IN_SET()..but it seems bad luck..Is there a better way to sort this out?
UPDATE
I used this query instead and it echoed only the first id's name in each row...
$query = $this->db
->select("tbl_attendance.*,tbl_students.name")
->from("tbl_attendance")
->join("tbl_students","tbl_students.student_id=tbl_attendance.attendance")
->where('FIND_IN_SET(tbl_students.student_id, tbl_attendance.attendance)')
->GROUP_BY('tbl_students.student_id')
->get()->result_array();
But as there are three numbers separated by commas in each row I want the rest to be echoed as well.
This Works
$query = $this->db
->select("td.Date, GROUP_CONCAT(ts.student_name SEPARATOR ',')")
->from("tbl_students AS ts")
->join("tbl_attendance AS ta","find_in_set(ts.st_id,ta.attendance)<> 0","left",false)
->get();
How about that ?
$query = $this->db
->select("td.Date, GROUP_CONCAT(ts.student_name)")
->from("tbl_students AS ts")
->join("tbl_attendance AS ta","find_in_set(ts.st_id,ta.attendance)","left",false)
->get();
You can try query like this,
SELECT a.`date`,group_concat(s.student_name)
FROM tbl_attendance a,tbl_students s
WHERE FIND_IN_SET(s.st_id, a.attendance) group by `date`;
Description :
FIND_IN_SET that allows you to find the position of a string within a comma-separated list of strings.
Syntax:
FIND_IN_SET(needle,haystack);
Hope this will solve your problem.
Here comma separated category IDs are saved in row 'category' eg., '12,15,7,19'
$category_ID = 15;
$this->db->select('*');
$this->db->from('products');
$this->db->where('FIND_IN_SET("'.$category_ID.'","category") <>','0');
$this->db->where('deleted','0');
$this->db->order_by('product_ID', 'DESC');
I hope this helps CI developers to use FIND_IN_SET.

how to set $_SESSION variable to use in sql query?

im not sure if i've got this right but i could do with some help to point me in the right direction please.
basically i have a table called ptb_stats. this table lay out looks like this:
user_id | user_postcode
1 m3 4
2 m3 4
3 kt1 3
4 sm2 7
i am trying to generate a mysql query that will bring up all the users that have matching postcodes.
so for instance if user 1 / user_id 1 is logged in then they will see user 2 who has the same postcode as them (begining with m3 4)
this tells the user aproximately that user 1 and user 2 are within 5 miles of each other as an example.
i've got a working query which is this:
function get_local_users() {
global $connection;
$query = "
SELECT *
From ptb_stats, ptb_users
WHERE ptb_stats.user_id=ptb_users.id
AND ptb_stats.user_postcode='m3 4'
AND ptb_users.id!=".$_SESSION['user_id']."";
$local_set = mysql_query($query, $connection);
confirm_query($local_set);
return $local_set;
}
at the moment im having to enter the postcode manually into the query for it to work. my problem is that i need to assign a session variable i believe which will tell the query to match users with the same postcodes to the user who is logged in.
at the moment i have $_SESSION['user_id'] set as a variable but someone previously set this variable and i am trying to fix all their work but am unable to get in touch with the guy who did it. So i don't understand session variables. i thought i could just change $_SESSION['user_id'] to $_SESSION['user_postcode'] and it would work, but basically what i need to do is some how get the query to say:
if the logged in user's user_postcode is (whatever value) and their are other users with matching user_postcodes then display these.
can someone please show me what i would need to do to get this to work. i would really appreciate it. thank you.
SELECT a.*
FROM
tableName a
INNER JOIN
(
SELECT user_postcode
FROM tableName
GROUP BY user_postcode
HAVING COUNT(*) > 1
) b ON a.user_postcode = b.user_postcode
SQLFiddle Demo
SQLFiddle Demo (with filter)
UPDATE 1
function get_local_users()
{
global $connection;
$query = " SELECT a.*
FROM ptb_stats a
INNER JOIN
(
SELECT user_postcode
FROM ptb_stats
GROUP BY user_postcode
HAVING COUNT(DISTINCT user_id ) > 1
) b ON a.user_postcode = b.user_postcode
WHERE a.user_id <> " . $_SESSION['user_id'];
$local_set = mysql_query($query, $connection);
confirm_query($local_set);
return $local_set;
}
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?

I want to get output result from second table based on first table rows output in json-php

I have knowledge of PHP but I am still learning Json. First of all I want to clear what I am looking for. I have two tables in mysql database, table1(users) and table2(business). Table "users" contains these rows(id, uid, business_name) and table "business" contains these rows(id, uid, category).
I have following code in PHP page:
if(isset($_GET['catName'])) {
$cat = $_GET['catName'];
$stmt = $pdo->prepare("SELECT id, uid, category FROM business WHERE category = ? ");
$stmt->execute(array($_GET['catName']));
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
I am able to get json output on my html page e.g.
101, 102, 103 and so on.
But I want to get business_name rows like ABC Business, XYZ Business, 123 Business and so on from second table "business" based on the output uid from first table. In brief, I want business_name output instead of uid output from second table.
Please help me. Thank you so much in advance.
You have an associative array, with the results from the query. It sounds like you want the business names, but you are not querying for them.
So the first step would be fix your broken query!
It's difficult to tell what you want from the query, but you're mixing the users table with the business table, so I'm guessing you really want business names based on users.
SELECT b.business_name FROM users u JOIN business b ON u.uid = b.uid WHERE category = ?
Then, you have to access your $arr variable correctly to get the business names
foreach ($arr as $bus_sql_result) {
echo $bus_sql_result['business_name']."\n";
}
This is not in JSON format, I'm not sure what JSON has to do with what you want, but if you really want it that way, you could try something like
$business_names = array();
foreach ($arr as $bus_sql_result) {
$business_names[] = $bus_sql_result['business_name'];
}
echo json_encode($business_names);
Thank you so much Chris and Jormundir. Joining the both tables really solved my problem. This is what I have done:
$stmt = $pdo->prepare("SELECT business.uid, users.business_name FROM business,users WHERE business.uid = users.uid AND business.category= ? ");
In html page I have put "business_name" array instead of "uid" and I have got result whatever I was looking for.
Thanks you so much all of you.

CodeIgniter query to see all post made by friend

I am working on a project based on CodeIgniter and MySQL. I need suggestions in building CodeIgniter query.
What I want to achieve:
I have 3 tables, profile, activity and friends. The structure for these tables is:
profile
user_id | name
activity
activity_id | message | user_id | sharewith | createdtime
friend
id | user1 | user2 | arefriends
Now I want to display all users' posts to everyone's / friends' walls according to who the user shares with. I have only two options for share with, either share with everyone or share with only friends.
For share with everyone I am storing 1 in the sharewith column of activity for the user_id and 2 for share only with friends.
I have built this query so far:
function load_activity()
{
$user_id=$this->session->userdata('user_id');
$this->db->select('*');
$this->db->from('activity');
$this->db->order_by("activity_id", "desc");
$this->db->limit(15);
$this->db->join('profile', 'profile.user_id = activity.user_id');
$query = $this->db->get();
foreach ($query->result() as $row){
$data[]=$row;
}
echo json_encode($data);
}
How can I modify this query to display either all activities which are shared with everyone or shared only with friends?
Thanks in advance.
It seems like the only thing you need is a WHERE clause.
If the user isn't a friend they should only be able to see the 'share with everyone' activity.
function load_activity() {
$user_id=$this->session->userdata('user_id');
$this->db->select('*');
$this->db->from('activity');
$this->db->order_by("activity_id", "desc");
$this->db->limit(15);
$this->db->join('profile', 'profile.user_id = activity.user_id');
if(!IS_FRIEND) {
$this->db->where('sharewith', 1);
}
$query = $this->db->get();
foreach ($query->result() as $row){
$data[]=$row;
}
echo json_encode($data);
}

Categories