I am failed to retrieve data using DB:table() in laravel - mysql

I am failed to retrieve any date with this code
$data = DB::table('students')
->where([
'students.school_id' => $school_id,
'students.status' => true,
'students.class' => $request->class,
'students.section' => $request->section,
'student_attendances.date' => "'$today'",
'students.school_id' => 'student_attendances.school_id'
])
->leftJoin('student_attendances', 'students.rfid_number', '=', 'student_attendances.uid')
->get();
above code returning this query:
select * from `students` left join `student_attendances` on `students`.`rfid_number` = `student_attendances`.`uid` where (`students`.`school_id` = 1 and `students`.`status` = 1 and `students`.`class` = 1 and `students`.`section` = 1 and `student_attendances`.`date` = '2020-03-16' and `students`.`school_id` = student_attendances.school_id)
I have tried this query in mysql database and successfully getting data.
And also below code is working fine :
$sql_query_text = "select * from students left join student_attendances on students.rfid_number = student_attendances.uid where (students.school_id = student_attendances.school_id and students.status = 1 and students.class = '{$request->class}' and students.section = '{$request->section}' and date(student_attendances.created_at) = '$today')";
$data = DB::select($sql_query_text);
I could not understand what is the fault. Please help. Thank you.

the problem is
'students.school_id' => 'student_attendances.school_id'
Joint table condition can not be used in ->where() so I use
->leftJoin('student_attendances', function($join){
$join->on('students.rfid_number', '=', 'student_attendances.uid');
$join->on('students.school_id', '=', 'student_attendances.school_id');
})
And this solved my purpose

Related

Zend Framework 2 SQL Join Issue

I am trying to use two left outer joins with Zend Framework 2's SQL classes but for some reason it is not returning one result but the other one is working fine. I've ran the actual SQL in MySQL Workbench and it returns just like I want but it is not doing it with Zend Framework. Here is my code:
Pure SQL:
SELECT groups.group_name, members.username, groups.id FROM groups
LEFT OUTER JOIN group_admins ON groups.id = group_admins.group_id
LEFT OUTER JOIN members ON group_admins.user_id = members.id
WHERE group_admins.user_id = " . parent::getUserId()['id']
This returns the result I wish, (which can be seen here: http://imgur.com/8ydmn4f)
Now, here is the Zend Framework 2 code I have in place:
$select_admins = new Select();
$select_admins->from(array(
'g' => 'groups',
))
->join(array(
'ga' => 'group_admins'
), 'g.id = ga.group_id')
->join(array(
'm' => 'members'
), 'ga.user_id = m.id', array('username'))
->where(array('ga.user_id' => parent::getUserId()['id']));
$query_group_admin = parent::$sql->getAdapter()->query(parent::$sql->buildSqlString($select_admins), Adapter::QUERY_MODE_EXECUTE);
$group_admins = array();
foreach ($query_group_admin as $group_admin) {
$group_admins[] = $group_admin;
}
// get the group members
$select = new Select();
$select->from(array(
'g' => 'group_members'
))
->join(array(
'm' => 'members'
), 'g.member_id = m.id')
->join(array(
'grp' => 'groups'
), 'g.group_id = grp.id')
->where(array(
'g.group_id' => $group_id
));
$query = parent::$sql->getAdapter()->query(parent::$sql->buildSqlString($select), Adapter::QUERY_MODE_EXECUTE);
$member_username = array();
foreach ($query as $member) {
$member_username[] = $member['username'];
}
// get the rest of the group info
$fetch = $this->gateway->select(array(
'id' => $group_id
));
$row = $fetch->current();
if (!$row) {
return false;
}
return array(
'admins' => implode(", ", $group_admins),
'members' => implode(", ", $member_username),
'info' => $row
);
Controller:
public function grouphomeAction()
{
$id = $this->params()->fromRoute('id', 0);
if (0 === $id) {
return $this->redirect()->toRoute('members/groups', array('action' => 'index'));
}
if (!$this->getGroupsService()->getGroupInformation($id)) {
return $this->redirect()->toRoute('members/groups', array('action' => 'index'));
}
return new ViewModel(array('group_info' => $this->getGroupsService()->getGroupInformation($id)));
}
However, this only shows the group name, group creator and group members but leave the group admins field empty.
Here is the print_r result of the array returned:
Array ( [admins] => [members] => jimmysole, fooboy [info] => ArrayObject Object ( [storage:ArrayObject:private] => Array ( [id] => 2 [group_name] => Tim's Group [group_creator] => timlinden [group_created_date] => 2017-01-16 17:39:56 ) ) )
If it helps, here is a screenshot as well of the page - http://imgur.com/xUQMaUu
Any help would be appreciated!
Thanks.
Basically your joins are INNER JOINS...I know....you must hate Zend right now :p . By default they are INNER JOINS so i assume that is what is wrong. SO try to specify the type of join and you should be fine. You can find more examples here: examples
$select12->from('foo')->join('zac', 'm = n', array('bar', 'baz'), Select::JOIN_OUTER);

Laravel Get Record ID from Update Query

For this update query, I'm trying to get the id after I run it.
$results = DB::table('testDB123.users')
->where('fbID', '=', $x['id'])
->update([
'updated_at' => $x['currDate'],
'fbFirstName' => $x['firstName'],
'fbLastName' => $x['lastName']
]
);
Tried this with no luck $results->id
Is there anything similar to insertGetId for update queries?
$id = DB::table($table1)->insertGetId([...])
update() method doesn't return an object, so you have two options:
Option 1
Use updateOrCreate():
$user = User::updateOrCreate(['fbID' => $x['id']], $dataArray);
$id = $user->id;
Option 2
Get an object and update it:
$user = User::where('fbID', '=', $x['id'])->first();
$user->update($dataArray);
$id = $user->id;

Zend DB Union Error

I have two query:
$select1 = $this->select()
->from(array('o'=>'table1'), array('*', 'o.field2 AS shared'))
->where('field4= ?', $input);
$select2 = $this->select()
->from(array('i'=>'table2'), array('*', 'ch.field1 AS shared'))
->where('ch.field5= ?', $input);
Both query works successfully. However, it does not work with the following union function even with shared parameter name. How come?
//Merge both query
$selectboth = $this->select()
->union(array($select1, $select2))
->order('shared');
$obj = $this->dbo->fetchRow($selectboth);
I am suspecting my fetchRow is the one causing this error in fetching.
if you have number of column same in both sql so you can ran into this issue:
http://framework.zend.com/issues/browse/ZF-4338
for example:
$select_q1 = $db->select()->...;
$select_q2 = $db->select()->...;
$main_select = $db->select()->union( array( '('.$select_q1 .')', '('.$select_q2 .')' ) );

Doctrine2 LEFT JOIN with 2 conditions

I'm trying to find a 'Product' by ID, and to left join all it's 'Photo' on two conditions: the locale AND the active state.
Here's my QueryBuilder :
$queryBuilder = $this->createQueryBuilder('p')
->select('p, photos, photoTranslation')
->leftJoin('p.photos', 'photos')
->leftJoin('photos.translations', 'photoTranslation')
->where('p.id = :id')
->andWhere('(photoTranslation.locale = :locale OR photoTranslation.locale IS NULL)')
->andWhere('(photoTranslation.active = :active OR photoTranslation.active IS NULL)')
->setParameters(array(
'id' => $id
'locale' => $this->getLocale(),
'active' => true
));
It works fine when there are no Photos or when there are ACTIVE photos, but not when there's an inactive Photo because it doesn't match one of the two conditions.
If I use only one condition, for instance only the locale part, it works fine :
$queryBuilder = $this->createQueryBuilder('p')
->select('p, photos, photoTranslation')
->leftJoin('p.photos', 'photos')
->leftJoin('photos.translations', 'photoTranslation')
->where('p.id = :id')
->andWhere('(photoTranslation.locale = :locale OR photoTranslation.locale IS NULL)')
->setParameters(array(
'id' => $id
'locale' => $this->getLocale()
));
For now, I loop on theses results and unset all inactive Photos... but I'd like a clean way to do in the QueryBuilder.
I also tried to put the conditions on the LEFT JOIN clause :
->leftJoin('photo.translations', 'phototTranslation', Doctrine\ORM\Query\Expr\JOIN::WITH, 'photoTranslation.locale = :locale AND photoTranslation.active = :active')
But it always returns the Photo, even if it's inactive.
For this problem a solution may be:
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
->select('p', 'pp')
->from('Product', 'p')
->leftJoin('p.photos', 'pp')
->leftJoin('pp.translations', 'ppt', Doctrine\ORM\Query\Expr\Join::WITH, $qb->expr()->andX(
$qb->expr()->eq('ppt.locale', ':locale'),
$qb->expr()->eq('ppt.active', ':active')
))
->where('p.id', ':productId')
->setParameters(
array(
'productId', $productId,
'active', $active,
'locale', $locale
)
);
$query = $qb->getQuery();
return $query->getResult(); // or ->getSingleResult();
NOTE: this example is the way to do it in Symfony2 (2.3) entity repository

Zend Framework 2: LEFT JOIN issue

public function getInterests($userID) {
$result = $this->tableGateway->select(function (Select $select) use ($userID) {
$select->join('interests', 'users_interests.interest_id = interests.interest_id', array('*'), 'left');
$where = new Where();
$where->equalTo('user_id', $userID);
$select->where($where);
});
return $result;
}
Here is my method. It simply selects all records from users_interests with user_id = $userID and joins the 'interests' table. So far, so good, but when trying to display the fetched results, the fields from the joined table just do not exist. Here is the dump of the $result:
Zend\Db\ResultSet\ResultSet Object
(
[allowedReturnTypes:protected] => Array
(
[0] => arrayobject
[1] => array
)
[arrayObjectPrototype:protected] => Object\Model\UsersInterests Object
(
[settings_id] =>
[user_id] =>
[interest_id] =>
)
[returnType:protected] => arrayobject
[buffer:protected] =>
[count:protected] => 2
[dataSource:protected] => Zend\Db\Adapter\Driver\Pdo\Result Object
(
[statementMode:protected] => forward
[resource:protected] => PDOStatement Object
(
[queryString] => SELECT `users_interests`.*, `interests`.* FROM `users_interests` LEFT JOIN `interests` ON `users_interests`.`interest_id` = `interests`.`interest_id` WHERE `user_id` = :where1
)
[options:protected] =>
[currentComplete:protected] =>
[currentData:protected] =>
[position:protected] => -1
[generatedValue:protected] => 0
[rowCount:protected] => 2
)
[fieldCount:protected] => 6
[position:protected] =>
)
I badly need help on this because I am supposed to finish my project until Sunday. Thanks in advance.
You can use the following to apply left join. $select::JOIN_LEFT instead of 'left'.
public function getInterests($userID) {
$result = $this->tableGateway->select(function (Select $select) use ($userID) {
$select->join('interests', 'users_interests.interest_id = interests.interest_id', array('*'), $select::JOIN_LEFT);
$where = new Where();
$where->equalTo('user_id', $userID);
$select->where($where);
});
return $result;
}
It seems you have a problem in the WHERE clause of the join. This also shows in the error here:
[queryString] => SELECT `users_interests`.*, `interests`.* FROM `users_interests` LEFT JOIN .
`interests` ON `users_interests`.`interest_id` = `interests`.`interest_id`
WHERE `user_id` = :where1
Try this:
$select->from($this->table)
->join('interests', 'users_interests.interest_id = interests.interest_id',
array('*'), 'left');
$where = new Where();
$where->equalTo('user_id', $userID) ;
$select->where($where);
I can not follow your code completely, like here:
$this->tableGateway->select(function (Select $select) use ($userID) {
But, here is a very nice article on this. I think, you can simplify your code a little.
Have you iterated over the resultset? You can see there's two matching rows:
[rowCount:protected] => 2
You have a ResultSet object, but it will not load any of the rows until requested, they are "lazy loaded" when you iterate over the object.
You can force the resultset to get them all for you:
var_dump($resultSet->toArray()); // force load all rows
or iterate over the ResultSet:
foreach($resultset as $row) {
var_dump($row); // each row loaded on request
}
I have written about this before and maybe it will help you as well.
TableGateway with multiple FROM tables