I am building a query involving a JOIN. This is the first time I've done db stuff with Active Record and I've hit a bit of a snag.
I want to join a table called companies to the users table so I can get the name of the company etc the user is in. I've done this sort of successfully like so:
function get_profile_by_username($username)
{
$this->db->join('companies', $this->table_name.'.company_id = companies.id');
$this->db->where('LOWER(username)=', strtolower($username));
$query = $this->db->get($this->table_name);
if ($query->num_rows() == 1) return $query->row();
return NULL;
}
However the issue being that the fields in companies, they are id and name are returned in that object as simply called name.
Normally when I would write the raw query I would give aliases to the tables and the result would be something like u.company_id, c.name. So I'd know name had nothing to do with the user but of course is the name of the company. And although not an issue now but potentially in the future, the id column obviously can't coexist in the result set, so one gets overwritten!
How can we get this sort of differentiating between the fields that come from certain tables? Or is there a better way of going about table joins and working with joined query data sets/objects?
Edit:
If I was doing it as a raw query I'd do:
SELECT u.id, u.username, c.name
FROM users AS u
JOIN companies AS c
ON c.id = u.company_id
WHERE u.username = 'foobar';
Which is great but if I tried to do that in active record I reckon that's pretty poor practice, if it works at all.
If you want to select some specific columns from table use db->select(). You can give alias to tables, add some conditions and etc. Send second parameter FALSE to not escape special characters.
$this->db->select('u.id, u.username, c.name', false);
$this->db->from('user as u');
$this->db->join('companies as c', 'u.company_id = c.id');
$this->db->where('LOWER(u.username)=', strtolower('foobar'));
$query = $this->db->get();
$this->db->select('ut.nombre as nombreu, ut.apellido, ru.nombre as nombrer');
$this->db->from('User_table ut');
$this->db->join('Role_usuario ru', 'ut.role_user = ru.Id');
$query = $this->db->get();`
`
Related
I want to join student_image table with student_details table where
image_id = student_id
but Im stuck here, the query gives the student details, but now I want to add the student image to be displayed together with the student
Below is my query
$query = $this->db->get_where('student_detail',array('reg_no'=>$reg_no))->result_array();
Are you using CodeIgniter?
If you want to display student_image also you can do it like this:
$this->db->select('*');
$this->db->from('student_image a');
$this->db->join('student_details b', 'a.image_id=b.student_detail_id','inner');
$this->db->where('b.student_detail',$reg_no);
return $this->db->get();
or you can do like it this:
$query = "select * from student_image as a join student_details as b on a.image_id=b.student_detail_id where b.student_detail=?"
return $this->db->query($query ,array($reg_no));
I hope this solves your problem
Myself, and probably anyone else has absolutely no idea what that db class you're using is, so we cannot help you with that detail.
A query like this is very basic. A plain query would look somewhat like this:
SELECT *
FROM student_details, student_image
WHERE student_details.studentID = student_image.studentID
And that's it. Now you have to translate it into working with your db class...
I would recommend you learn basic mysql queries before you start using special pre-made classes. They make things a lot more complicated when you do not know what you want it to do yet.
-- The above query will get you the student details only if the row actually exists in both tables.
If you want it back even if it doesn't exist, you could use a LEFT JOIN, like so:
SELECT *
FROM student_details
LEFT JOIN student_image ON student_details.ID = student_image.ID
WHERE student_details.ID = 'myStudentID'
The above query would retrieve a student's results.
I am trying to form a query for MySQL where it gets all the info from multiple tables but only displays the ones where the "activity" = "Other". Right now it is displaying everyones info and I don't know the proper way to format the WHERE part of the query. I want it to access the jobSearch table, read the activity and only return the ones where the activity is "Other"
$query_student = " SELECT *
FROM student
JOIN major
ON student.studentID=major.studentID
JOIN jobSearch
ON major.studentID=jobSearch.studentID
WHERE jobSearch.activity == Other";
You SQL syntax is wrong, it should be:
SELECT * FROM table_name WHERE column = value
In your case:
SELECT * FROM student ... WHERE jobSearch.activity = 'Other'
For reference, check this good tutorial about SQL syntax: http://www.tutorialspoint.com/sql/sql-where-clause.htm
Your SQL syntax is OK is not wrong
SELECT *
FROM student
JOIN major ON student.studentID=major.studentID
JOIN jobSearch ON major.studentID=jobSearch.studentID
WHERE jobSearch.activity = 'Other';
If jobsearch.activity field is a varchar use single quotes around the word Other and use only one "=".
Also I recommend using alias and not using "Select *", you might run into a problem because you have the same field name in different tables, try to use something like this.
SELECT st.*, mj.field1, mj.field2, js.activity, js.field2
FROM student st
JOIN major mj ON st.studentID=mj.studentID
JOIN jobSearch js ON mj.studentID=js.studentID
WHERE js.activity = 'Other';
I have 2 tables, a users table and a trade table.
Which look like:
The structure of my code right now is:
<?php
$history = mysqli_query($con, "SELECT * FROM .......");
while($row = mysqli_fetch_array($history)) {
echo("The sentence");
} ?>
Problem I'm facing is that I'm trying to echo the user_name which in one case has to be the receiver and other the person giving it.
Pro tip: Never use SELECT * in software unless you know exactly why you are doing so. In your case it is harmful.
I'm assuming your query is really against the user and trade tables you mentioned in your question.
First, recast your query using 21st century SQL, as follows:
SELECT *
FROM trade AS t
JOIN user AS s ON s.user_id = t.user_id_sender
WHERE s.facebook_id = $fbid
Second, use this to retrieve your user's names and the item id traded.
SELECT s.user_name AS sender,
r.user_name AS receiver,
t.trade_id AS item_id
FROM trade AS t
JOIN user AS s ON s.user_id = t.user_id_sender
JOIN user AS r ON r.user_id = t.user_id_receiver
WHERE s.facebook_id = $fbid
See how we JOIN the user table twice, with two different aliases s (for sender) and r (for receiver)? That's the trick to fetching both names from IDs.
See how we employ the aliases sender and receiver to disambiguate the two user_name columns in the result set?
Now, when you use the php fetch_array function, you'll end up with these elements in the array.
$history['sender']
$history['receiver']
$history['item_id']
The array index strings correspond to the alias names you specified in your SELECT clause in your query.
So, one reason to avoid SELECT * is that you can get more than one column with the same name, and that means fetch_array will eliminate those duplicates and so it will lose useful information from your result set.
This question already has answers here:
How to resolve ambiguous column names when retrieving results?
(11 answers)
Closed 2 years ago.
I have fields that have the same name in different tables that I'm joining. Such as ticket.status, user.status and transaction.status. At the moment the query returns just status.
How can I get the table name in such a way that it stops similar field names from overwriting and so I can tell the difference between the fields.
Simply put:
$data = array($eventId);
$statement = $this->db->prepare("SELECT * FROM ticket, user, transaction
WHERE ticket.eventId = ?
AND ticket.userId = user.userId
AND ticket.transactionId = transaction.transactionId");
$statement->execute($data);
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
In my research I've found the constant PDO::ATTR_FETCH_TABLE_NAMES that looks like it could help, but I do not know how to implement ( I assume through $statement->setAttribute(); somehow).
I also have concerns that it will not work, as the PHP documentation mentions it is dependent on the driver.
Thanks
Just add new aliases to your select statements
$statement = $this->db->prepare("
SELECT *, ticket.status AS ticket_status, user.status AS user_status, transaction.status AS transaction_status
FROM ticket, user, transaction
WHERE ticket.eventId = ?
AND ticket.userId = user.userId
AND ticket.transactionId = transaction.transactionId
");
Then you can do
$rows[0]['user_status'];
$rows[0]['ticket_status'];
$rows[0]['transaction_status'];
If you are really concern by performance, the quantity of data returned will be greater so instead of adding new aliases you can select every single columns and while you do so put an alias on the status column.
Why not change your to actually join instead:
SELECT
t.status as ticket_status, u.status as user_status, tr.status as trans_status
FROM
ticket as t
inner join user as u on t.userId = u.userId
inner join transaction as tr on t.transactionId = tr.transactionId
where
t.eventId = ?
You don't even need to cast the tables using as something but I find it's neater.
Note, its the casting of the columns that will actually fix this issue, not the join method.
The most obvious comment is "don't do it, that's why aliases exist". But there's still a good underlying question: does MySQL send information about where a result-set column comes from (table, view or calculated)?
Apparently, it does, since the PDOStatement object has an experimental method called getColumnMeta(). I've been testing and it returns an associative array where the table key
contains the source table if column comes from a table or view
is an empty string if the column is calculated
Of course, I'd stick to aliases anyway. Being able to use associative arrays is a killer feature for me.
I am query a database to get all the employers names out of my database, but I only want to get the ones where their ID is present in my jobs table, here is what I am trying to do.
$this->db->select('*')
->from('employers')
->join('jobwall', 'jobwall.employers_employer_id = employers.employer_id', 'left');
However this does not return the correct results, how can I select all my employers from the employers table but only if they have data in the jobwall table?
You need to add a WHERE clause:
$sql = '
SELECT *
FROM employers
LEFT JOIN jobwall ON jobwall.employers_employer_id = employers.employer_id
WHERE employers.employer_id
IN (SELECT employers_employer_id FROM jobwall)
';
$this->db->query($sql);
I'm not sure how complicated this would be to create using Codeigniter's activerecord class.
I think a better WHERE clause might be:
SELECT *
FROM employers
LEFT JOIN jobwall ON jobwall.employers_employer_id = employers.employer_id
WHERE jobwall.id IS NOT NULL
This will exclude any rows that don't have a corresponding job.
You should use whatever Primary Key your jobwall table has if jobwall.id doesn't exist.
This can also be written using ActiveRecord easily.
I don't understand you exactly, but I think you should use join without left:
this->db->select('*')->from('employers')->join('jobwall', 'jobwall.employers_employer_id = employers.employer_id');