I am setting 1 row per page in symfony pager but its showing more data than 1. It is because my query is left joining the sfGuardUser table with other tables and it is causing duplication of 'sfGuardUser' row in some cases when there are multiple entries in 'license' table for that particular user ! Here is my query:
$pager = new sfDoctrinePager('sfGuardUser', '1');
$q = Doctrine_Query::create()
->select('u.id, u.username, g.name, l.id, l.status, l.client_id, l.vendor_id, l.applied_date, p.org_name')
->from('sfGuardUser u')
->leftJoin('u.Profile p')
->leftJoin('u.Groups g')
->leftJoin('u.LicensedClients l')
->where('g.name = \'vendor\'')
->orderBy('l.applied_date');
$q->setHydrationMode(Doctrine_Core::HYDRATE_SCALAR);
$pager->setQuery($q);
$pager->setPage($request->getParameter('page', 1));
$pager->init();
The pagination is there, but problem is in some cases there are multiple rows shown in one page when there are multiple rows for a particular user in the license table. How can I implement it in a right way ?
What do you want to achieve with joining user and license table (1:n relation) when paging through (sfGuard)Users ?
If you want to sort users by license type/date/count, you could use
DISTINCT u.id, u.username
Related
I'm trying to retrieve data from database to laravel blade view with join associate table.
in my case I have two tables called interesting_courses and courses. here some student can have many interesting courses. Therefore courses_id stored as json array in database as follows.
["1","11","15","16"]
but I need to join the courses table to get the associate course name as follows.
["Hospitality","Business Management","Auto Mobile","Health Care"]
Below is my controller
$intresting_courses = DB::table('intresting_courses')
->join('courses','courses.id','=','intresting_courses.courses_id')
->where('intresting_courses.youth_id',$id)
->first();
How can I join the tables.
There is no way you can join it in query natively.
The solution is to write two queries
select * from intresting_courses where youth_id = ? limit 1
select * from courses where id in (1, 2, 3, 4, 5, ...)
that way you can get courses that student intresting.
Here the laravel code for thoses queries.
$intresting_courses = DB::table('intresting_courses')
->where('intresting_courses.youth_id', $id)
->first();
$courses = DB::table('courses')
->whereIn('id', json_decode($intresting_courses->courses_id))
->get();
I'm using luman and Database Query Builder to fetch full user info from database.
First, Please Take a lock at my database structure:
I have a table called users and a series of other tables that are related to user groups (Ex: secretaries, patients, doctors and admins) which stores additional information about the users.
Also To determine user access, I have a level column on user table which can have one of this value as enum: 'admin', 'doctor', 'secretary', 'patient'.
So, I want to get this information using one query by join and select.
My training code is something like this:
$userInfo = User::where("userID", $userID)
->limit(1)
->join('[GROUP_TABLE_NAME]', function ($join) {
$join->on('user.userID', '=', '[GROUP_TABLE_NAME]' .'.'.
'[GROUP_NAME]' . 'ID');
})
->get();
The GROUP_NAME comes from level column on user table and the GROUP_TABLE_NAME can be built based on the GROUP_NAME value(Ex: ['secretary' => 'secretaries' , 'patient' => 'patients' , ...]).
Any idea to handle the join structure using laravel query builder?
First you should be aware of the fact that this code architecture is not convenient and not easy to understand for other developers.
SQL
You can achieve your goal by using union and join.
Just convert this query for laravel builder or use it directly with DB::statement: select users.*, infos.info from users left join (( select secretaries.* from secretaries ) UNION (select doctors.* from doctors)) infos ON users.id = infos.user_id where users.id=?.
But
The easiest way to do it is to fetch info in two queries, both indexed and fast: user from users by primary key and then info by indexed field user_id in it. Create Doctorinfo, Admininfo models and correspondent migrations. So user class can be smth like this:
public function getInfo() {
switch($this->level) {
'doctor':
return $this->doctorinfo;
...
}
}
private function doctorinfo() {
$this->hasOne('App\Doctorinfo');
}
Builder
You can use left join to join all sub tables as well. The following builder selects info column.
User::where("userID", $userID)->limit(1)
->leftJoin('patients', 'users.id', '=', 'patients.user_id')
->leftJoin('doctors', 'users.id', '=', 'doctors.user_id')
->leftJoin('admins', 'users.id', '=', 'admins.user_id')
->select('users.*', DB::raw('IF(users.level="admin", admins.info, (IF users.level="doctors", doctors.info, patients.info))'))
I have 2 tables that i want to join & show the name of user's role. here's the situation
My 2 tables are users_mlh & user_roles_mlh
on the role column of users_mlh table i'm storing the ID of user role, user_roles_mlh contains the name & id of user role. what i want to do is show the name of the user role in my view.
my tables as follows.
i have tried this in my model
$this->db->select('*');
$this->db->from('user_roles_mlh');
$this->db->join('users_mlh', 'users_mlh.role = user_roles_mlh.id');
$this->db->where('users_mlh.role = user_roles_mlh.id');
$query = $this->db->get();
return $query->result_array();
but from above i get something like this
at the moment it lists all user level not the role of each individual user
Case 1 : If you Directly want to Access all data without using where condition
$this->db->select( "*" );
$this->db->from( 'users_mlh' );
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
Case 2: With Where Condition and specific column data
$this->db->select( 'user_roles_mlh.role_type,users_mlh.name' );
$this->db->from( 'users_mlh' );
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
$this->db->where('users_mlh.id =',1);
And finally get the results by
$query = $this->db->get();
return $query->result();
No need to write separate query for getting role name. Join Roles table when you fetching users data..
$this->db->select('users_mlh.*,user_roles_mlh.role_type');
$this->db->from('users_mlh');
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
$query = $this->db->get();
return $query->result_array();
Try this.
If I use your tables, you should have the following request:
SELECT users_mlh.*, JOIN user_roles_mlh.role_type
FROM users_mlh -- list all users
LEFT JOIN user_roles_mlh -- and joind by roles
ON users_mlh.role = user_roles_mlh.id -- condition for joining
With this request, you will have all your users, with the role text associated.
So, if this request works, use the same logic on your ORM
I have this code for an active record query in codeigniter:
$this->db->join('user', 'user.id = purchase_req.owner_id', 'inner');
$this->db->where('user.employer_id', $User->employer_id);
$Purchase_req = $this->Purchase_req->find();
In a view without the join statement, $Purchase_req->id would return the actual purchase request id. In the view with the join, $Purchase_req->id returns the user id. How can I join the tables together, and still get the purchase request id, instead of it changing to the user.id?
The id you want to achieve is the ambiguous for mysql because the both tables have the id columns therefore when you tries to access the $Purchase_req->id it will return the last id column which is from the purchase_req table you need to assingn the unique aliases for the same columns in the joined table like
$this->db->select('`user`.*,`purchase_req`.*,`user`.id AS user_id')
$this->db->join('user', 'user.id = purchase_req.owner_id', 'inner');
$this->db->where('user.employer_id', $User->employer_id);
$Purchase_req = $this->Purchase_req->find();
Now when you echo $Purchase_req->user_id it will return the user.id
Basically, I've got this coding convention that any primary key which is an ID, I will call the column name "id". So here comes my problem. I'm joining two tables and I'm getting the ID of the second table instead of the first table. I know if I use select "artists.id, ..." it will work, but I want to know if there's a fix with using "select *" which would be better for future expansion (new colums will come ...).
Here's my model:
$this->db->select('*');
$this->db->from('artists');
$this->db->join('categories', 'artists.category_id = categories.id');
$this->db->where('id', $id);
$this->db->limit(1);
With Print_R I can see I'm getting all columns (but only 1 id, which is from the categories table instead of artists table) without any table prefix.
You should qualify your columns with a table alias
$this->db->select('a.id as artist_id, c.id as category_id, a.column2,c.column3');
$this->db->from('artists a');
$this->db->join('categories c', 'a.category_id = c.categories.id');
$this->db->where('a.id', $id);
$this->db->limit(1);
If you want to continue using SELECT *
$this->db->select('a.*, c.*, a.id as artist_id, c.id as category_id');
$this->db->from('artists a');
$this->db->join('categories c', 'a.category_id = c.categories.id');
$this->db->where('a.id', $id);
$this->db->limit(1);
Keep in mind, that the LAST duplicate column will be returned. So, a.*,c.* will return c.id as id and c.*,a.* will return a.id as id.
I think to save you trouble and for the future, always use the table in front of the column name.
There is no logic here, when you look for * it means all fields, in Oracle for example you will get all fields with the table in front, i guess in MySQL it doesn't, but if i were you, i would not risk it.