I can already do this using the follow SQL command
SELECT * FROM users AS u INNER JOIN messages AS m ON u.ID IN (m.senderID, m.recipientID) WHERE u.ID <> $userID GROUP BY u.ID ORDER BY m.created_at DESC
How do I convert it to Laravel query builder, I have a Message model and User model
Do like this :
$users = User::join('messages', 'users.ID', '=', 'messages.user_id')
->whereIn('users.ID',['messages.senderId', 'messages.recipientID'])
->where('users.ID', '!=', $userID)
->groupBy('users.ID')
->orderBy('created_at','DESC')
->get();
$UserMessage = Message::where('from_user', $user_id)
->orWhere('to_user', $user_id)->latest()->get();
$usersChat = $UserMessage->map(function ($conversation) {
if ($conversation->from_user === auth()->id()) {
return $conversation->receiver;
}
return $conversation->sender;
})->unique();
return $usersChat;
and in message model
public function sender() {
return $this->belongsTo(User::class, 'from_user');
}
public function receiver() {
return $this->belongsTo(User::class, 'to_user');
}
Related
I have three models:
Rental.php
class Rental extends Model
{
use SoftDeletes;
public function rentalItem()
{
return $this->hasMany('App\Models\RentalItem');
}
}
RentalItem.php
class RentalItem extends Model
{
public function rentalAsset()
{
return $this->belongsTo('App\Models\RentalAsset');
}
public function rental()
{
return $this->belongsTo('App\Models\Rental');
}
}
and RentalAsset.php
class RentalAsset extends Model
{
public function rentalItem()
{
return $this->hasMany('App\Models\RentalItem');
}
}
One Rental can have many RentalItems which belongs to RentalAsset.
RentalAsset is product card for each RentalItem so one RentalItem can have one RentalAsset.
When RentalItem is created, first it needs to check if it is available in date interval. This done by checking whether between date_from and date_two is some Rental which has RentalItem related to RentalAsset.
I want a query, which will return all RentalAssets which are not related to any RentalItem being related to Rental during those dates.
Unfortunately, this is not working right:
$freeAssets = RentalAsset::where('rental_asset_category_id', '=', $request->rental_asset_category_id)
->whereDoesntHave('rentalItem.rental', function($query) use($date_from, $date_to)
{
$query->where('date_from', '<=', $date_to);
$query->where('date_to', '>=', $date_from);
})
->get();
Your help is highly appreciated!
Thanks a lot.
UPDATE:
using Laravel 5.6
UPDATE 2:
I sput out generated select by the provided eloquent query:
select * from `rental_assets` where `rental_asset_category_id` = ? and exists
(select * from `rental_items` where `rental_assets`.`id` = `rental_items`.`rental_asset_id` and not exists
(select * from `rentals` where `rental_items`.`rental_id` = `rentals`.`id`
and `date_from` <= ? and `date_to` >= ? and `rentals`.`deleted_at` is null))
and `rental_assets`.`deleted_at` is null
And this select returns what I need:
select * from `rental_assets` where `rental_asset_category_id` = 2
and not exists (
select * from `rental_items` where `rental_assets`.`id` = `rental_items`.`rental_asset_id` and exists
(select * from `rentals` where `rental_items`.`rental_id` = `rentals`.`id`
and `date_from` <= '2018-12-12' and `date_to` >= '2018-01-01' and `rentals`.`deleted_at` is null))
and `rental_assets`.`deleted_at` is null;
What is the correct eloquent query? I would rather that then raw query.
thanks.
This is probably what you need here:
$freeAssets = RentalAsset::where('rental_asset_category_id', $request->rental_asset_category_id)
->whereDoesntHave('rentalItem', function($query) use ($date_from, $date_to) {
$query->whereHas('rental', function($query) use ($date_from, $date_to) {
$query->where('date_from', '<=', $date_to);
$query->where('date_to', '>=', $date_from);
});
})->get();
Feedback
User
This query works.Fetching datas in feedback table:
public function feedback_data()
{
$recipe_id = 0;
$this->db->where('recipe_id',$recipe_id);
$query = $this->db->get('feedback');
return $query->result_array();
}
I need to fetch feedback_id and comment from feedback table and firstname and lastname from user table where user_id from feedback is equal to user_id from user. By the way, here's my query and i think it's not working.
$this->db->select('f.feedback_id, f.comment, f.recipe_id, f.user_id as Fid'.'u.firstname, u.lastname, u.user_id as Uid');
$this->db->from('feedback f')
$this->db->join('user u','u.user_id = f.user_id');
$this->db->where('f.recipe_id', $recipe_id);
$query = $this->db->get()->result();
return $query;
Please try this :
$this->db->select('f.feedback_id, f.comment, f.recipe_id, f.user_id as Fid'.'u.firstname, u.lastname, u.user_id as Uid');
$this->db->from('feedback f')
$this->db->join('user u','u.user_id = f.user_id', 'left');
$this->db->where('f.recipe_id', $recipe_id);
$query = $this->db->get()->result();
return $query;
Try this if the above code does not work :
$this->db->select('f.feedback_id, f.comment, f.recipe_id, f.user_id as Fid'.'u.firstname, u.lastname, u.user_id as Uid');
$this->db->from('feedback f');
$this->db->join('user u','u.user_id = f.user_id', 'left');
$this->db->where('f.recipe_id', $recipe_id);
$query = $this->db->get();
if ($query->num_rows() > 0)
{
return $query->row_array();
}
I'm trying to do the following query:
public function findByNotifications($ownerId)
{
$em = $this->getEntityManager();
$query = $em->createQuery('
SELECT n FROM
(SELECT n FROM DelivveWebBundle:UserAd n
INNER JOIN n.ad ad
WHERE ad.owner = :ownerId
LIMIT 20
UNION
SELECT n FROM DelivveWebBundle:UserAd n
INNER JOIN n.user u
INNER JOIN n.ad ad
WHERE u.id = :ownerId
AND ad.status = :progress
LIMIT 20)
notofication
LIMIT 20;
')->setParameter('ownerId', $ownerId)
->setParameter('progress', Constant::AD_IN_PROGRESS);
$result = $query->getResult();
return $result;
}
to generate all my notifications:
public function showNotificationsAction()
{
$this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');
$owner = $this->getUser();
$repository = $this->getDoctrine()->getRepository('DelivveWebBundle:UserAd');
$notifications = $repository->findByAdOwner($owner->getId());
return $this->render('DelivveWebBundle:Ad:notification.html.twig', array(
'owner' => $owner,
'notifications' => $notifications
));
}
The idea is to do a search on AdUser table that returns all notifications that have ads that logged User owns, along with any notifications that logged User requested.
Notification the User requested is a line of AdUser table that has the column the user logged in User.
I decided to breaking in two searches and giving a marge in results
public function findByAdOwner($ownerId)
{
$qb = $this->getEntityManager()->createQueryBuilder('n');
return $qb->select('n')
->from('DelivveWebBundle:UserAd', 'n')
->join('n.ad', 'ad')
->where('ad.owner = :ownerId')
->setParameter('ownerId', $ownerId)
->setMaxResults(20)
->getQuery()
->getResult();
}
public function findByUserNotify($userId)
{
$qb = $this->getEntityManager()->createQueryBuilder('n');
return $qb->select('n')
->from('DelivveWebBundle:UserAd', 'n')
->join('n.ad', 'ad')
->where('n.user = :userId')
->andWhere('ad.status = :status')
->setParameter('userId', $userId)
->setParameter('status', Constant::AD_IN_PROGRESS)
->setMaxResults(20)
->getQuery()
->getResult();
}
public function findNotifcations($userId){
$notification = $this->findByAdOwner($userId);
$append = $this->findByUserNotify($userId);
return array_merge($notification, $append);
}
To become more readable'll just put after something that distinguishes the two types of notice to do the treatment on the page.
I discovered that there is a way to add commands to the doctrine that does not exist, but appears to be quite complex if anyone knows do this, put the answer please.
How to get an array by Executing this query in Yii?
SELECT `sevrity_id`,COUNT(*) FROM `Incident` GROUP BY `sevrity_id`
I need an array like this: array(1=>20,2=10,3=12)
public function getSevrityCounts()
{
$data = array();
$command = Yii::app()->db->createCommand('SELECT sevrity_id,COUNT(*) AS num FROM Incident GROUP BY sevrity_id');
foreach($command->queryAll() as $row) {
$data[ $row['sevrity_id'] ] = $row['num'];
}
return $data;
}
How can I write the following SQL in LINQ to Entities?
SELECT r.rolename,
( CASE
WHEN ur.username IS NULL THEN 0
ELSE 1
END ) AS isinrole
FROM bgt.roles r
LEFT OUTER JOIN bgt.usersinroles ur
ON ur.rolename = r.rolename
AND ur.username = 'ADMIN'
This worked for me. Thanks for all the suggestions.
var query =
from r in Roles
from ur in UsersInRoles
.Where(v => v.Rolename == r.Rolename && v.Username == "ADMIN")
.DefaultIfEmpty()
select new { Rolename = r.Rolename, IsInRole = (ur.Username != null) };
The generated SQL is as follows
SELECT
1 AS [C1],
[Extent1].[Rolename] AS [Rolename],
CASE WHEN ([Extent2].[Username] IS NOT NULL) THEN cast(1 as bit) WHEN ([Extent2].[Username] IS NULL) THEN cast(0 as bit) END AS [C2]
FROM [bgt].[Roles] AS [Extent1]
LEFT OUTER JOIN [bgt].[UsersInRoles] AS [Extent2] ON ([Extent2].[Rolename] = [Extent1].[Rolename]) AND ('ADMIN' = [Extent2].[Username])
I would do it like this:
from role in db.Roles
let isInRole = role.UsersInRoles.Any(u => u.UserName == "ADMIN")
select new { role.RoleName, isInRole }
Althought the generated SQL is not as nice as yours.
Extension method for Left join (linq to entities):
public static class DbSetExtensions
{
public static IQueryable<TResult2> LeftJoin<TOuter, TInner, TKey, TResult2>(
this IQueryable<TOuter> outerList,
IEnumerable<TInner> innerList,
Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<LeftJoinTemp<TOuter, TInner>, TInner, TResult2>> resultSelector2)
{
// (tr, historicPrices) => new { tr, historicPrices }
Expression<Func<TOuter, IEnumerable<TInner>, LeftJoinTemp<TOuter, TInner>>> myResultSelector1
= (tr, historicPrices) => new LeftJoinTemp<TOuter, TInner> { outer = tr, inners = historicPrices };
// e => e.historicPrices.DefaultIfEmpty()
Expression<Func<LeftJoinTemp<TOuter, TInner>, IEnumerable<TInner>>> myCollectionSelector
= e => e.inners.DefaultIfEmpty();
//var a = outerList.GroupJoin(innerList, outerKeySelector, innerKeySelector, resultSelector1);
var a = outerList.GroupJoin(innerList, outerKeySelector, innerKeySelector, myResultSelector1);
//return a.SelectMany(collectionSelector, resultSelector2);
var b = a.SelectMany(myCollectionSelector, resultSelector2);
return b;
}
}
public class LeftJoinTemp<TOuter, TInner>
{
public TOuter outer;
public IEnumerable<TInner> inners;
}
example calling, left join of Transaction and HistoricPrice, for transaction you have to write parent.outer
.LeftJoin(db.HistoricPrices,
transaction => new { transaction.InstrumentId, DateId = transaction.Date2Id },
historicPrice => new { historicPrice.InstrumentId, historicPrice.DateId },
(parent, historicPrice) => new
{
parent.outer.Id,
parent.outer.OpeningDate,
parent.outer.InstrumentName,
historicPrice.DateId,
historicPrice.InstrumentId
})