I have 2 tables one of them stores students and the other one managers
students have name surname,
eventually managers have name and surname too.
I also store added_by in students table to check which manager added the student.
With the query I join tables
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get();
lets say student is
Name Surname Added_by
Jon Doe 1
and Manager is
id name surname
1 jane doe
So when I join those 2 tables with the query I give above. My student becomes
Jane doe because of name conflicts in those 2 tables.
Simply manager's name overwrites to student's name since both columns named same.
I could actually join only some columns in managers table however I need this name column to print out added_by column with the managers name
and of course I can change columns name to something else in a table however this would be too much work because I have to refactor each query in my application one by one and also test everything from scratch
so my question is how can I join those 2 tables and prevent conflictions on columns with same name?
Try using this:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->select('students.*','managers.name as m_name','managers.surname as m_s_name','managers.other_column_if_needed','managers.another_column_if_needed')
->get();
This way your managers table's name column will be treated as m_name and surname column will be treated as m_s_name
I ran into a similar issue earlier today, the 'get' method takes in an array of the column names which you want in the result as parameter. Therefore to prevent the conflicts you have to give those columns an alias name like so :
$students = \App\Student::with('payment')->with('discontinuities')
->Join('managers','students.added_by','=','managers.id')
->get(['students.*', 'managers.name as managers_name', 'managers.surname as managers_surname', 'managers.other_column_if_needed']);
My guess would be that you should specify column names and tables in the get() part of your query.
example:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get(['managers.Name', 'managers.Surname', 'students.name', 'students.surname']);
Related
I have a problem in my project
I'm trying to do a query with the table "Asignaciones", this table save the records for students and teachers asignations. (The teachers can comment the works of students and can see only the students that are asigned) The principal problem is that all the users is on the same table and when i try to return a names just have one.
$asignaciones = DB::table('asignaciones')
->join('users as students','students.id',
'=','asignaciones.id_student')
->join('users as teachers','teachers.id',
'=','asignaciones.id_teacher')
->select('asignaciones.id','students.name',
'teachers.name')->get();
return $asignaciones;
I need to get two names (Maybe changing the column name like a users table) to show in a table
Thanks for your time and answers! :)
Define unique aliases in your select clause for student name and teacher name
->select('asignaciones.id','students.name as student_name','teachers.name as teacher_name');
Right now single alias name is returned for teacher and student name in the returned result set, object cannot have 2 keys with same name so one of the names got override while laravel maps the DB result to object or collection of objects
I have a table called sitekeys:
In this site_key contains a unique license. And The field called licenses contains the no of times it can be used. the org_id field contains the company to which it has been assigned.
Now the activation table:
in this table site_key contains the keys assigned to the device.
Now I want to count The keys used for a company.
Like for XYZ company i has give 10 licenes then i want to know how many of them are used by it, so for that i can count(site_key) in activation table.
So what should be my query here?
I think i wil have to use Group_BY to do so.
I want show the keys i gave to a company and the keys they have used
i don't know exactly the design of your table so safely i have to join the two table
SELECT a.org_id, a.licenses, b.used_key from sitekeys a
LEFT JOIN
(
SELECT site_key, user_id, count(site_key) as used_key
FROM
activation b
GROUP BY site_key,user_id
) b
on a.site_key = b.site_key
$this->db->select("count(activation.site_key)");
$this->db->from("activation");
$this->db->join("sitekeys");
$this->db->group_by("sitekeys.site_key");
$this->db->get();
Try this
I'm using codeigniter.
We have two mysql tables.
What I'm doing is taking all the details in the first table and feeding it to an html page to let all users to view it. But now I want to add some details from a second table related to a column in first table.
I mean, I have a column in first table call "Pending_on" in that column I have inserted some branch names
and in the second table I have inserted the contact details of those departments.
So, if we think in the first table fifth row pending_on column has the value "HR" then I want to display the telephone number of the HR department.
So, how can I write a query for this?
For your case, here is an example:
There are 2 tables named entry and subscription.
entry
field1 publisherId
field2 entry
subscription
field1 myId
field2 friendId
You can use a JOIN. In plain SQL:
SELECT e.publisherId, e.entry
FROM entry e
JOIN subscription s
ON s.friendId = e.publisherId
WHERE s.myId = 1234
this is the query i used to do my work
and thanks goes to MR. Yuvvaraj Bathrabagu
$this->db->select('*');
$this->db->from('new_users');
$this->db->join('contact', 'new_users.pending_on = contact.dep','left');
$query = $this->db->get();
$data = $query->result_array();
Let's take your example. You have a column name pending_on in your first table, and in your second table you have your department_name column. Find the below code for joining those two tables,
$this->db->select('firsttable.*,secondtable.contact_details');
$this->db->from('firsttable');
$this->db->join('secondtable', 'firsttable.pending_on = secondtable.department_name','left');
$query = $this->db->get();
So, The department_name in second table and pending_on in first table should have the same value as you mentioned "HR". And my suggestion is to have the id's of the table as reference instead of department names. Hope This helps.
I have a publications database and I need to fetch some information regarding the author. The author field is such that the authors have been lumped together in one field e.g if a book has two authors called Robert Ludlum and John Grisham, in the database it is saved as Ludlum, R.;Grisham,J.;
My application needs to spool information and retrieve data on books authored by a particular author if they click on their name. I am using this statement to retrieve the data
$select = "SELECT tblPublications.Title, tblPublications.Year FROM tblPublications WHERE tblPublications.Authors LIKE '%$sname%'";
$sname is a variable referring to the surname of the author. The problem arises if two authors share the same surname. however a workaround I am trying to implement is to get the applicationtake the surname, insert a comma, take the first name of a user and get the first letter then combine the result to a stringe and match them to each comma delimited value in the author field e.g if it is Grisham's books I am looking for I use *Grisham, J.* in my query.
Any Idea how to do this in PHP,MYSQL?
If it is possible to redesign the database, you should probably have an authors table and a book_authors table that relates books to authors, so that multiple authors can be associated with each book. Where is the Last Name coming from that the user clicks? Is it possible to have the link generated be LastName, First letter of first name? If so then you can probably change the link so it will include the first letter. But it is still possible to have two authors with the same last name and first letter of first name. So I think the best solution is to have an authors table and a Book_authors table and just store the author id as a hidden field and use that to retrieve the books by the selected author.
Your database design is incorrect, you have not normalized the data.
If you use like to search with leading wildcards, you will kill any chance of using an index.
Your only option to fix (if you want to keep the mistaken CSV data) is to convert the table to MyISAM format and put a FULLTEXT index on the authors field.
You can then search for an author using
SELECT fielda, b,c FROM table1 WHERE MATCH(authors) against ('$lastname')
See: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Of course a better option would be to normalize the database and create a separate table for authors with a link table.
TABLE books
------------
id primary key
other book data
TABLE authors
--------------
id primary key
lastname varchar (indexed)
other author data
TABLE author_book_link
----------------------
author_id
book_id
PRIMARY KEY ab (author_id, book_id)
Now you can query using very fast indexes using something like:
SELECT b.name, b.ISBN, a.name
FROM books b
INNER JOIN author_book_link ab ON (ab.book_id = b.id)
INNER JOIN author a ON (a.id = ab.author_id)
WHERE a.lastname = '$lastname'
It would entirely depend on what input you are getting from the user.
If the user just types a name, then there isn't much you can do (as there is no guarantee that they will enter it in a correct format for you to parse).
If you are getting them to type in a firstname and lastname however, something like this could be done:
<?php
$firstname = trim(mysql_real_escape_string($_GET['fname']));
$surname = trim(mysql_real_escape_string($_GET['sname']));
$firstletter = substr($_GET['fname'],0,1);
$sname = $surname.', '.$firstletter;
$select = "SELECT tblPublications.Title,
tblPublications.Year
FROM tblPublications
WHERE tblPublications.Authors LIKE '%$sname%'";
I have 3 employers IDs: 1, 2 and 3. I am generating tasks for each one by adding a line in database and in column "for_emp" I insert IDs I want to assign this task for and could be all 3 of them separated by comma. So let's say I got a task and "for_emp" is "1,2,3", the employers IDs. If I would like to select all tasks for the ID 2, will I be able to select from the row that has "1,2,3" as IDs and just match "2" there ? If not, how do you suggest I insert my emp IDs into one row in database ? The db is MySQL.
Any ideas ? Thanks.
Don't do it like that, you should normalize your database.
What you want to do is have a table such as task, and then task_assignee. task_assignee would have fields task_id and user_id. If a task has eg. three assignees (IDs 1, 2 and 3), then you'll create three rows in the task_assignee table for that one task, like this:
+--------+---------+
|task_id | user_id |
+--------+---------+
| 1 | 1 [
| 1 | 2 [
| 1 | 3 [
+--------+---------+
Then it's just a simple matter of querying the task_assignee table to find all tasks that are assigned to a given user.
Here's an example of how to get all the tasks for user_id 2:
SELECT t.* FROM task AS t INNER JOIN task_assignee AS ta WHERE ta.user_id = 2
EDIT.
Just as a related note, even if you didn't do it the right way (which I described in my answer previously), doing it with hacks such as LIKE would still be far from the optimal solution. If you did store a list of comma-separated values, and needed to check if eg. the value 2 is in the list, you could use the MySQL's FIND_IN_SET function:
SELECT * FROM task WHERE FIND_IN_SET(2, for_emp)
But you shouldn't do this unless you have no choice (eg. you're working with someone's shitty DB design), because it's way more inefficient and won't let you index the the employee ID.
The following query should do what you want:
SELECT * FROM tasks WHERE for_emp LIKE '%2%';
However, be aware that that would also match employers 12, 20, 21 etc; so take care if you expect you might end up in double-digits.
However, the other answers about renormalising your database are definitely preferable.
You're doing it wrong. Create a relation table with two fields: employee id and task id. If one task should be assigned to three employees, insert three rows in the relation table.
You then use JOIN to join the task, employee and relation tables.
then its no proper relation...
I would suggest a "mapping table" for the n:m relation
employee
id
task
id
employeetask
task_id
employee_id
Make a table for your employers. Insert your three rows in it.
Then make a table for mapping tasks to employers. If a task is assigned to three employers, insert three rows into this table. This is basic entity-relation work.
I would make 2 different tables.
1 with employees, and 1 with tasks.
then make another table which combines the two tables, I will call it Assigned Tasks.
Then in assigned tasks I make a assigned id, a employeenumber which is a FK to the employee table and a taskid which is a FK to the Tasks table.
If an employee has more than 1 task. Just insert another row in the assigned table. ;)
When its about Databases, try to think in solo entities! Combining those entities is able in antoher table.
sql example:
Select * from Assignedtasks where employeeID = 1 will give you all his/her tasks. :)
You could use a LIKE '%,2,%' clause in your SELECT statement.
eg:
SELECT * FROM table where for_emp LIKE '%,2,%'
However performance of such non-sargable queries is usually quite bad.
I would suggest that you insert a row each for each employee who is assigned to the task using a separate TASK_EMPLOYEE_MAPPING table with taskId, employeeId as a composite primary key.
With such a design, your query will be
SELECT * FROM TASK_EMPLOYEE_MAPPING WHERE employeeId = '2'